Coverage Report

Created: 2026-09-28 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/validator/formchecker.h
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
//===-- wasmedge/validator/formchecker.h - Form checking class definition -===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contains the declaration of the FormChecker class, which helps
12
/// validator to check types in stack with instructions.
13
///
14
//===----------------------------------------------------------------------===//
15
#pragma once
16
17
#include "ast/instruction.h"
18
#include "ast/module.h"
19
#include "common/errcode.h"
20
#include "common/span.h"
21
22
#include <cstddef>
23
#include <cstdint>
24
#include <unordered_set>
25
#include <utility>
26
#include <vector>
27
28
namespace WasmEdge {
29
namespace Validator {
30
31
typedef std::optional<ValType> VType;
32
33
1.61M
static inline constexpr VType unreachableVType() { return VType(); }
Unexecuted instantiation: component.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: validator.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: component_validator.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: component_type.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: component_canon.cpp:WasmEdge::Validator::unreachableVType()
formchecker.cpp:WasmEdge::Validator::unreachableVType()
Line
Count
Source
33
1.61M
static inline constexpr VType unreachableVType() { return VType(); }
Unexecuted instantiation: component_context.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: wasm_c.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: wasmedge.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: fuzzTool.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: validateTool.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: instantiateTool.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: compilerTool.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: runtimeTool.cpp:WasmEdge::Validator::unreachableVType()
Unexecuted instantiation: vm.cpp:WasmEdge::Validator::unreachableVType()
34
35
class FormChecker {
36
public:
37
13.6k
  FormChecker() = default;
38
39
  void reset(bool CleanGlobal = false);
40
  Expect<void> validate(AST::InstrView Instrs, Span<const ValType> RetVals);
41
  Expect<void> validate(const ValType &VT) const noexcept;
42
43
  /// Adder of contexts
44
  void addType(const AST::SubType &Type);
45
  void addFunc(const uint32_t TypeIdx, const bool IsImport = false);
46
  void addTable(const AST::TableType &Tab);
47
  void addMemory(const AST::MemoryType &Mem);
48
  void addGlobal(const AST::GlobalType &Glob, const bool IsImport = false);
49
  void addElem(const AST::ElementSegment &Elem);
50
  void addData(const AST::DataSegment &Data);
51
  void addRef(const uint32_t FuncIdx);
52
  void addLocal(const ValType &V, bool Initialized);
53
  void addTag(const uint32_t TypeIdx);
54
55
0
  std::vector<VType> result() { return ValStack; }
56
129k
  auto &getTypes() const { return Types; }
57
24.2k
  auto &getFunctions() { return Funcs; }
58
9.64k
  auto &getTables() { return Tables; }
59
7.31k
  auto &getMemories() { return Mems; }
60
3.51k
  auto &getGlobals() { return Globals; }
61
92
  auto &getTags() { return Tags; }
62
22.7k
  uint32_t getNumImportFuncs() const { return NumImportFuncs; }
63
220
  uint32_t getNumImportGlobals() const { return NumImportGlobals; }
64
65
  /// Helper function
66
  ValType VTypeToAST(const VType &V);
67
68
  /// Control frame
69
  struct CtrlFrame {
70
    CtrlFrame() = default;
71
    CtrlFrame(struct CtrlFrame &&F)
72
220k
        : StartTypes(std::move(F.StartTypes)), EndTypes(std::move(F.EndTypes)),
73
220k
          Jump(F.Jump), Height(F.Height), InitedLocal(F.InitedLocal),
74
220k
          IsUnreachable(F.IsUnreachable), Code(F.Code) {}
75
    CtrlFrame(const struct CtrlFrame &F)
76
9.44k
        : StartTypes(F.StartTypes), EndTypes(F.EndTypes), Jump(F.Jump),
77
9.44k
          Height(F.Height), InitedLocal(F.InitedLocal),
78
9.44k
          IsUnreachable(F.IsUnreachable), Code(F.Code) {}
79
    CtrlFrame(Span<const ValType> In, Span<const ValType> Out,
80
              const AST::Instruction *J, size_t H, size_t LocalH,
81
              OpCode Op = OpCode::Unreachable)
82
85.4k
        : StartTypes(In.begin(), In.end()), EndTypes(Out.begin(), Out.end()),
83
85.4k
          Jump(J), Height(H), InitedLocal(LocalH), IsUnreachable(false),
84
85.4k
          Code(Op) {}
85
    std::vector<ValType> StartTypes;
86
    std::vector<ValType> EndTypes;
87
    const AST::Instruction *Jump;
88
    size_t Height;
89
    size_t InitedLocal;
90
    bool IsUnreachable;
91
    OpCode Code;
92
  };
93
94
  struct LocalType {
95
    LocalType(ValType VT, bool Initialized = false)
96
338M
        : IsInit(Initialized), VType(VT) {}
97
    bool IsInit;
98
    const ValType VType;
99
  };
100
101
private:
102
  /// Checking expression
103
  Expect<void> checkExpr(AST::InstrView Instrs);
104
105
  /// Checking instruction list
106
  Expect<void> checkInstrs(AST::InstrView Instrs);
107
108
  /// Instruction iteration
109
  Expect<void> checkInstr(const AST::Instruction &Instr);
110
111
  /// Stack operations
112
  void pushType(VType);
113
  void pushTypes(Span<const VType> Input);
114
  void pushTypes(Span<const ValType> Input);
115
  Expect<VType> popType();
116
  Expect<VType> popType(ValType E);
117
  Expect<void> popTypes(Span<const ValType> Input);
118
  void pushCtrl(Span<const ValType> In, Span<const ValType> Out,
119
                const AST::Instruction *Jump,
120
                OpCode Code = OpCode::Unreachable);
121
  Expect<CtrlFrame> popCtrl();
122
  Span<const ValType> getLabelTypes(const CtrlFrame &F);
123
  Expect<void> unreachable();
124
  Expect<void> StackTrans(Span<const ValType> Take, Span<const ValType> Put);
125
  Expect<void> StackPopAny();
126
127
  /// Contexts.
128
  std::vector<const AST::SubType *> Types;
129
  std::vector<uint32_t> Funcs;
130
  std::vector<std::pair<TypeCode, ValType>> Tables;
131
  std::vector<TypeCode> Mems;
132
  std::vector<std::pair<ValType, ValMut>> Globals;
133
  std::vector<ValType> Elems;
134
  std::vector<uint32_t> Datas;
135
  std::unordered_set<uint32_t> Refs;
136
  uint32_t NumImportFuncs = 0;
137
  uint32_t NumImportGlobals = 0;
138
  std::vector<LocalType> Locals;
139
  std::vector<uint32_t> LocalInits;
140
  std::vector<ValType> Returns;
141
  std::vector<uint32_t> Tags;
142
143
  /// Running stack.
144
  std::vector<CtrlFrame> CtrlStack;
145
  std::vector<VType> ValStack;
146
};
147
148
} // namespace Validator
149
} // namespace WasmEdge