/src/WasmEdge/include/validator/formchecker.h
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 | | //===-- 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 | 974k | static inline constexpr VType unreachableVType() { return VType(); } Unexecuted instantiation: wasmedge.cpp:WasmEdge::Validator::unreachableVType() Unexecuted instantiation: fuzzTool.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() Unexecuted instantiation: validator.cpp:WasmEdge::Validator::unreachableVType() Unexecuted instantiation: validator_component.cpp:WasmEdge::Validator::unreachableVType() formchecker.cpp:WasmEdge::Validator::unreachableVType() Line | Count | Source | 33 | 974k | static inline constexpr VType unreachableVType() { return VType(); } |
|
34 | | |
35 | | class FormChecker { |
36 | | public: |
37 | 3.80k | FormChecker() = default; |
38 | 3.80k | ~FormChecker() = default; |
39 | | |
40 | | void reset(bool CleanGlobal = false); |
41 | | Expect<void> validate(AST::InstrView Instrs, Span<const ValType> RetVals); |
42 | | Expect<void> validate(const ValType &VT) const noexcept; |
43 | | |
44 | | /// Adder of contexts |
45 | | void addType(const AST::SubType &Type); |
46 | | void addFunc(const uint32_t TypeIdx, const bool IsImport = false); |
47 | | void addTable(const AST::TableType &Tab); |
48 | | void addMemory(const AST::MemoryType &Mem); |
49 | | void addGlobal(const AST::GlobalType &Glob, const bool IsImport = false); |
50 | | void addElem(const AST::ElementSegment &Elem); |
51 | | void addData(const AST::DataSegment &Data); |
52 | | void addRef(const uint32_t FuncIdx); |
53 | | void addLocal(const ValType &V, bool Initialized); |
54 | | void addTag(const uint32_t TypeIdx); |
55 | | |
56 | 0 | std::vector<VType> result() { return ValStack; } |
57 | 30.0k | auto &getTypes() const { return Types; } |
58 | 19.3k | auto &getFunctions() { return Funcs; } |
59 | 2.54k | auto &getTables() { return Tables; } |
60 | 2.51k | auto &getMemories() { return Mems; } |
61 | 52 | auto &getGlobals() { return Globals; } |
62 | 0 | auto &getTags() { return Tags; } |
63 | 15.2k | uint32_t getNumImportFuncs() const { return NumImportFuncs; } |
64 | 21 | uint32_t getNumImportGlobals() const { return NumImportGlobals; } |
65 | | |
66 | | /// Helper function |
67 | | ValType VTypeToAST(const VType &V); |
68 | | |
69 | | /// Control frame |
70 | | struct CtrlFrame { |
71 | | CtrlFrame() = default; |
72 | | CtrlFrame(struct CtrlFrame &&F) |
73 | 80.9k | : StartTypes(std::move(F.StartTypes)), EndTypes(std::move(F.EndTypes)), |
74 | 80.9k | Jump(F.Jump), Height(F.Height), InitedLocal(F.InitedLocal), |
75 | 80.9k | IsUnreachable(F.IsUnreachable), Code(F.Code) {} |
76 | | CtrlFrame(const struct CtrlFrame &F) |
77 | 2.63k | : StartTypes(F.StartTypes), EndTypes(F.EndTypes), Jump(F.Jump), |
78 | 2.63k | Height(F.Height), InitedLocal(F.InitedLocal), |
79 | 2.63k | IsUnreachable(F.IsUnreachable), Code(F.Code) {} |
80 | | CtrlFrame(Span<const ValType> In, Span<const ValType> Out, |
81 | | const AST::Instruction *J, size_t H, size_t LocalH, |
82 | | OpCode Op = OpCode::Unreachable) |
83 | 28.6k | : StartTypes(In.begin(), In.end()), EndTypes(Out.begin(), Out.end()), |
84 | 28.6k | Jump(J), Height(H), InitedLocal(LocalH), IsUnreachable(false), |
85 | 28.6k | Code(Op) {} |
86 | | std::vector<ValType> StartTypes; |
87 | | std::vector<ValType> EndTypes; |
88 | | const AST::Instruction *Jump; |
89 | | size_t Height; |
90 | | size_t InitedLocal; |
91 | | bool IsUnreachable; |
92 | | OpCode Code; |
93 | | }; |
94 | | |
95 | | struct LocalType { |
96 | | LocalType(ValType VT, bool Initialized = false) |
97 | 8.43M | : IsInit(Initialized), VType(VT) {} |
98 | | bool IsInit; |
99 | | const ValType VType; |
100 | | }; |
101 | | |
102 | | private: |
103 | | /// Checking expression |
104 | | Expect<void> checkExpr(AST::InstrView Instrs); |
105 | | |
106 | | /// Checking instruction list |
107 | | Expect<void> checkInstrs(AST::InstrView Instrs); |
108 | | |
109 | | /// Instruction iteration |
110 | | Expect<void> checkInstr(const AST::Instruction &Instr); |
111 | | |
112 | | /// Stack operations |
113 | | void pushType(VType); |
114 | | void pushTypes(Span<const VType> Input); |
115 | | void pushTypes(Span<const ValType> Input); |
116 | | Expect<VType> popType(); |
117 | | Expect<VType> popType(ValType E); |
118 | | Expect<void> popTypes(Span<const ValType> Input); |
119 | | void pushCtrl(Span<const ValType> In, Span<const ValType> Out, |
120 | | const AST::Instruction *Jump, |
121 | | OpCode Code = OpCode::Unreachable); |
122 | | Expect<CtrlFrame> popCtrl(); |
123 | | Span<const ValType> getLabelTypes(const CtrlFrame &F); |
124 | | Expect<void> unreachable(); |
125 | | Expect<void> StackTrans(Span<const ValType> Take, Span<const ValType> Put); |
126 | | Expect<void> StackPopAny(); |
127 | | |
128 | | /// Contexts. |
129 | | std::vector<const AST::SubType *> Types; |
130 | | std::vector<uint32_t> Funcs; |
131 | | std::vector<ValType> Tables; |
132 | | uint32_t Mems = 0; |
133 | | std::vector<std::pair<ValType, ValMut>> Globals; |
134 | | std::vector<ValType> Elems; |
135 | | std::vector<uint32_t> Datas; |
136 | | std::unordered_set<uint32_t> Refs; |
137 | | uint32_t NumImportFuncs = 0; |
138 | | uint32_t NumImportGlobals = 0; |
139 | | std::vector<LocalType> Locals; |
140 | | std::vector<uint32_t> LocalInits; |
141 | | std::vector<ValType> Returns; |
142 | | std::vector<uint32_t> Tags; |
143 | | |
144 | | /// Running stack. |
145 | | std::vector<CtrlFrame> CtrlStack; |
146 | | std::vector<VType> ValStack; |
147 | | }; |
148 | | |
149 | | } // namespace Validator |
150 | | } // namespace WasmEdge |