Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/include/ast/component/canonical.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/ast/component/canonical.h - Canon class definitions ------===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contains the declaration of the Canon node related classes.
12
///
13
//===----------------------------------------------------------------------===//
14
#pragma once
15
16
#include "ast/expression.h"
17
#include "ast/type.h"
18
19
#include <vector>
20
21
namespace WasmEdge {
22
namespace AST {
23
namespace Component {
24
25
// canonopt ::= 0x00                  => string-encoding=utf8
26
//            | 0x01                  => string-encoding=utf16
27
//            | 0x02                  => string-encoding=latin1+utf16
28
//            | 0x03 m:<core:memidx>  => (memory m)
29
//            | 0x04 f:<core:funcidx> => (realloc f)
30
//            | 0x05 f:<core:funcidx> => (post-return f)
31
//            | 0x06                  => async ๐Ÿ”€
32
//            | 0x07 f:<core:funcidx> => (callback f) ๐Ÿ”€
33
//            | 0x08                  => always-task-return ๐Ÿ”€
34
35
// TODO: COMPONENT - collect the canonopt into a class.
36
37
class Memory {
38
public:
39
0
  uint32_t getMemIndex() const noexcept { return MemIdx; }
40
0
  uint32_t &getMemIndex() noexcept { return MemIdx; }
41
42
private:
43
  uint32_t MemIdx;
44
};
45
46
class Realloc {
47
public:
48
0
  uint32_t getFuncIndex() const noexcept { return FnIdx; }
49
0
  uint32_t &getFuncIndex() noexcept { return FnIdx; }
50
51
private:
52
  uint32_t FnIdx;
53
};
54
55
class PostReturn {
56
public:
57
0
  uint32_t getFuncIndex() const noexcept { return FnIdx; }
58
0
  uint32_t &getFuncIndex() noexcept { return FnIdx; }
59
60
private:
61
  uint32_t FnIdx;
62
};
63
64
enum class StringEncoding : Byte {
65
  UTF8 = 0x00,
66
  UTF16 = 0x01,
67
  Latin1 = 0x02,
68
};
69
70
/// AST Component::CanonOpt aliasing.
71
using CanonOpt = std::variant<StringEncoding, Memory, Realloc, PostReturn>;
72
73
// canon ::= 0x00 0x00 f:<core:funcidx> opts:<opts> ft:<typeidx>
74
//           => (canon lift f opts type-index-space[ft])
75
//         | 0x01 0x00 f:<funcidx> opts:<opts>
76
//           => (canon lower f opts (core func))
77
//         | 0x02 rt:<typeidx>    => (canon resource.new rt (core func))
78
//         | 0x03 rt:<typeidx>    => (canon resource.drop rt (core func))
79
//         | 0x07 rt:<typeidx>
80
//           => (canon resource.drop rt async (core func)) ๐Ÿ”€
81
//         | 0x04 rt:<typeidx>    => (canon resource.rep rt (core func))
82
//         | 0x08                 => (canon backpressure.set (core func)) ๐Ÿ”€
83
//         | 0x09 rs:<resultlist> opts:<opts>
84
//           => (canon task.return rs opts (core func)) ๐Ÿ”€
85
//         | 0x05                 => (canon task.cancel (core func)) ๐Ÿ”€
86
//         | 0x0a 0x7f i:<u32>    => (canon context.get i32 i (core func)) ๐Ÿ”€
87
//         | 0x0b 0x7f i:<u32>    => (canon context.set i32 i (core func)) ๐Ÿ”€
88
//         | 0x0c async?:<async>? => (canon yield async? (core func)) ๐Ÿ”€
89
//         | 0x06 async?:<async?>
90
//           => (canon subtask.cancel async? (core func)) ๐Ÿ”€
91
//         | 0x0d                 => (canon subtask.drop (core func)) ๐Ÿ”€
92
//         | 0x0e t:<typeidx>     => (canon stream.new t (core func)) ๐Ÿ”€
93
//         | 0x0f t:<typeidx> opts:<opts>
94
//           => (canon stream.read t opts (core func)) ๐Ÿ”€
95
//         | 0x10 t:<typeidx> opts:<opts>
96
//           => (canon stream.write t opts (core func)) ๐Ÿ”€
97
//         | 0x11 t:<typeidx> async?:<async?>
98
//           => (canon stream.cancel-read async? (core func)) ๐Ÿ”€
99
//         | 0x12 t:<typeidx> async?:<async?>
100
//           => (canon stream.cancel-write async? (core func)) ๐Ÿ”€
101
//         | 0x13 t:<typeidx> => (canon stream.close-readable t (core func)) ๐Ÿ”€
102
//         | 0x14 t:<typeidx> => (canon stream.close-writable t (core func)) ๐Ÿ”€
103
//         | 0x15 t:<typeidx> => (canon future.new t (core func)) ๐Ÿ”€
104
//         | 0x16 t:<typeidx> opts:<opts>
105
//           => (canon future.read t opts (core func)) ๐Ÿ”€
106
//         | 0x17 t:<typeidx> opts:<opts>
107
//           => (canon future.write t opts (core func)) ๐Ÿ”€
108
//         | 0x18 t:<typeidx> async?:<async?>
109
//           => (canon future.cancel-read async? (core func)) ๐Ÿ”€
110
//         | 0x19 t:<typeidx> async?:<async?>
111
//           => (canon future.cancel-write async? (core func)) ๐Ÿ”€
112
//         | 0x1a t:<typeidx> => (canon future.close-readable t (core func)) ๐Ÿ”€
113
//         | 0x1b t:<typeidx> => (canon future.close-writable t (core func)) ๐Ÿ”€
114
//         | 0x1c opts:<opts> => (canon error-context.new opts (core func)) ๐Ÿ“
115
//         | 0x1d opts:<opts>
116
//           => (canon error-context.debug-message opts (core func)) ๐Ÿ“
117
//         | 0x1e                 => (canon error-context.drop (core func)) ๐Ÿ“
118
//         | 0x1f                 => (canon waitable-set.new (core func)) ๐Ÿ”€
119
//         | 0x20 async?:<async>? m:<core:memidx>
120
//           => (canon waitable-set.wait async? (memory m) (core func)) ๐Ÿ”€
121
//         | 0x21 async?:<async>? m:<core:memidx>
122
//           => (canon waitable-set.poll async? (memory m) (core func)) ๐Ÿ”€
123
//         | 0x22                 => (canon waitable-set.drop (core func)) ๐Ÿ”€
124
//         | 0x23                 => (canon waitable.join (core func)) ๐Ÿ”€
125
//         | 0x40 ft:<typeidx>    => (canon thread.spawn_ref ft (core func)) ๐Ÿงต
126
//         | 0x41 ft:<typeidx> tbl:<core:tableidx>
127
//           => (canon thread.spawn_indirect ft tbl (core func)) ๐Ÿงต
128
//         | 0x42 => (canon thread.available_parallelism (core func)) ๐Ÿงต
129
// opts   ::= opt*:vec(<canonopt>) => opt*
130
// async? ::= 0x00 => ฯต
131
//          | 0x01 => async
132
133
// TODO: COMPONENT - collect the canon into a class.
134
135
// Currently implementing:
136
//   0x00 0x00 (canon lift f opts type-index-space[ft])
137
//   0x01 0x00 (canon lower f opts (core func))
138
//   0x02      (canon resource.new rt (core func))
139
//   0x03      (canon resource.drop rt (core func))
140
//   0x04      (canon resource.rep rt (core func))
141
142
class Lift {
143
public:
144
0
  uint32_t getCoreFuncIndex() const noexcept { return CoreFnIdx; }
145
0
  uint32_t &getCoreFuncIndex() noexcept { return CoreFnIdx; }
146
0
  Span<const CanonOpt> getOptions() const noexcept { return Opts; }
147
0
  std::vector<CanonOpt> &getOptions() noexcept { return Opts; }
148
0
  uint32_t getFuncTypeIndex() const noexcept { return FnTyIdx; }
149
0
  uint32_t &getFuncTypeIndex() noexcept { return FnTyIdx; }
150
151
private:
152
  uint32_t CoreFnIdx;
153
  std::vector<CanonOpt> Opts;
154
  uint32_t FnTyIdx;
155
};
156
157
class Lower {
158
public:
159
0
  uint32_t getFuncIndex() const noexcept { return FnIdx; }
160
0
  uint32_t &getFuncIndex() noexcept { return FnIdx; }
161
0
  Span<const CanonOpt> getOptions() const noexcept { return Opts; }
162
0
  std::vector<CanonOpt> &getOptions() noexcept { return Opts; }
163
164
private:
165
  uint32_t FnIdx;
166
  std::vector<CanonOpt> Opts;
167
};
168
169
class ResourceNew {
170
public:
171
0
  uint32_t getTypeIndex() const noexcept { return TyIdx; }
172
0
  uint32_t &getTypeIndex() noexcept { return TyIdx; }
173
174
private:
175
  uint32_t TyIdx;
176
};
177
178
class ResourceDrop {
179
public:
180
0
  uint32_t getTypeIndex() const noexcept { return TyIdx; }
181
0
  uint32_t &getTypeIndex() noexcept { return TyIdx; }
182
183
private:
184
  uint32_t TyIdx;
185
};
186
187
class ResourceRep {
188
public:
189
0
  uint32_t getTypeIndex() const noexcept { return TyIdx; }
190
0
  uint32_t &getTypeIndex() noexcept { return TyIdx; }
191
192
private:
193
  uint32_t TyIdx;
194
};
195
196
using Canon = std::variant<Lift, Lower, ResourceNew, ResourceDrop, ResourceRep>;
197
198
} // namespace Component
199
} // namespace AST
200
} // namespace WasmEdge
201
202
template <>
203
struct fmt::formatter<WasmEdge::AST::Component::Canon>
204
    : fmt::formatter<std::string_view> {
205
  fmt::format_context::iterator
206
  format(const WasmEdge::AST::Component::Canon &Opt,
207
0
         fmt::format_context &Ctx) const noexcept {
208
0
    using namespace std::literals;
209
0
210
0
    fmt::memory_buffer Buffer;
211
0
    if (std::holds_alternative<WasmEdge::AST::Component::Lift>(Opt)) {
212
0
      fmt::format_to(std::back_inserter(Buffer), "lift"sv);
213
0
    } else if (std::holds_alternative<WasmEdge::AST::Component::Lower>(Opt)) {
214
0
      fmt::format_to(std::back_inserter(Buffer), "lower"sv);
215
0
    } else if (std::holds_alternative<WasmEdge::AST::Component::ResourceNew>(
216
0
                   Opt)) {
217
0
      fmt::format_to(std::back_inserter(Buffer), "resource-new"sv);
218
0
    } else if (std::holds_alternative<WasmEdge::AST::Component::ResourceDrop>(
219
0
                   Opt)) {
220
0
      fmt::format_to(std::back_inserter(Buffer), "resource-drop"sv);
221
0
    } else if (std::holds_alternative<WasmEdge::AST::Component::ResourceRep>(
222
0
                   Opt)) {
223
0
      fmt::format_to(std::back_inserter(Buffer), "resource-rep"sv);
224
0
    } else {
225
0
      fmt::format_to(std::back_inserter(Buffer), "!!!unknown"sv);
226
0
    }
227
0
228
0
    return formatter<std::string_view>::format(
229
0
        std::string_view(Buffer.data(), Buffer.size()), Ctx);
230
0
  }
231
};