Coverage Report

Created: 2025-08-25 06:58

/src/WasmEdge/lib/loader/ast/component/component_canonical.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 "loader/loader.h"
5
6
namespace WasmEdge {
7
namespace Loader {
8
9
0
Expect<void> Loader::loadCanonical(AST::Component::Canonical &C) {
10
0
  auto ReportError = [this](auto E) {
11
0
    return logLoadError(E, FMgr.getLastOffset(), ASTNodeAttr::Comp_Canonical);
12
0
  };
Unexecuted instantiation: component_canonical.cpp:auto WasmEdge::Loader::Loader::loadCanonical(WasmEdge::AST::Component::Canonical&)::$_0::operator()<WasmEdge::ErrCode>(WasmEdge::ErrCode) const
Unexecuted instantiation: component_canonical.cpp:auto WasmEdge::Loader::Loader::loadCanonical(WasmEdge::AST::Component::Canonical&)::$_0::operator()<WasmEdge::ErrCode::Value>(WasmEdge::ErrCode::Value) const
13
  // canon ::= 0x00 0x00 f:<core:funcidx> opts:<opts> ft:<typeidx>
14
  //           => (canon lift f opts type-index-space[ft])
15
  //         | 0x01 0x00 f:<funcidx> opts:<opts>
16
  //           => (canon lower f opts (core func))
17
  //         | 0x02 rt:<typeidx>    => (canon resource.new rt (core func))
18
  //         | 0x03 rt:<typeidx>    => (canon resource.drop rt (core func))
19
  //         | 0x07 rt:<typeidx>
20
  //           => (canon resource.drop rt async (core func)) ๐Ÿ”€
21
  //         | 0x04 rt:<typeidx>    => (canon resource.rep rt (core func))
22
  //         | 0x08                 => (canon backpressure.set (core func)) ๐Ÿ”€
23
  //         | 0x09 rs:<resultlist> opts:<opts>
24
  //           => (canon task.return rs opts (core func)) ๐Ÿ”€
25
  //         | 0x05                 => (canon task.cancel (core func)) ๐Ÿ”€
26
  //         | 0x0a 0x7f i:<u32>    => (canon context.get i32 i (core func)) ๐Ÿ”€
27
  //         | 0x0b 0x7f i:<u32>    => (canon context.set i32 i (core func)) ๐Ÿ”€
28
  //         | 0x0c async?:<async>? => (canon yield async? (core func)) ๐Ÿ”€
29
  //         | 0x06 async?:<async?>
30
  //           => (canon subtask.cancel async? (core func)) ๐Ÿ”€
31
  //         | 0x0d                 => (canon subtask.drop (core func)) ๐Ÿ”€
32
  //         | 0x0e t:<typeidx>     => (canon stream.new t (core func)) ๐Ÿ”€
33
  //         | 0x0f t:<typeidx> opts:<opts>
34
  //           => (canon stream.read t opts (core func)) ๐Ÿ”€
35
  //         | 0x10 t:<typeidx> opts:<opts>
36
  //           => (canon stream.write t opts (core func)) ๐Ÿ”€
37
  //         | 0x11 t:<typeidx> async?:<async?>
38
  //           => (canon stream.cancel-read async? (core func)) ๐Ÿ”€
39
  //         | 0x12 t:<typeidx> async?:<async?>
40
  //           => (canon stream.cancel-write async? (core func)) ๐Ÿ”€
41
  //         | 0x13 t:<typeidx>
42
  //           => (canon stream.close-readable t (core func)) ๐Ÿ”€
43
  //         | 0x14 t:<typeidx>
44
  //           => (canon stream.close-writable t (core func)) ๐Ÿ”€
45
  //         | 0x15 t:<typeidx> => (canon future.new t (core func)) ๐Ÿ”€
46
  //         | 0x16 t:<typeidx> opts:<opts>
47
  //           => (canon future.read t opts (core func)) ๐Ÿ”€
48
  //         | 0x17 t:<typeidx> opts:<opts>
49
  //           => (canon future.write t opts (core func)) ๐Ÿ”€
50
  //         | 0x18 t:<typeidx> async?:<async?>
51
  //           => (canon future.cancel-read async? (core func)) ๐Ÿ”€
52
  //         | 0x19 t:<typeidx> async?:<async?>
53
  //           => (canon future.cancel-write async? (core func)) ๐Ÿ”€
54
  //         | 0x1a t:<typeidx>
55
  //           => (canon future.close-readable t (core func)) ๐Ÿ”€
56
  //         | 0x1b t:<typeidx>
57
  //           => (canon future.close-writable t (core func)) ๐Ÿ”€
58
  //         | 0x1c opts:<opts> => (canon error-context.new opts (core func)) ๐Ÿ“
59
  //         | 0x1d opts:<opts>
60
  //           => (canon error-context.debug-message opts (core func)) ๐Ÿ“
61
  //         | 0x1e                => (canon error-context.drop (core func)) ๐Ÿ“
62
  //         | 0x1f                => (canon waitable-set.new (core func)) ๐Ÿ”€
63
  //         | 0x20 async?:<async>? m:<core:memidx>
64
  //           => (canon waitable-set.wait async? (memory m) (core func)) ๐Ÿ”€
65
  //         | 0x21 async?:<async>? m:<core:memidx>
66
  //           => (canon waitable-set.poll async? (memory m) (core func)) ๐Ÿ”€
67
  //         | 0x22                => (canon waitable-set.drop (core func)) ๐Ÿ”€
68
  //         | 0x23                => (canon waitable.join (core func)) ๐Ÿ”€
69
  //         | 0x40 ft:<typeidx>   => (canon thread.spawn_ref ft (core func)) ๐Ÿงต
70
  //         | 0x41 ft:<typeidx> tbl:<core:tableidx>
71
  //           => (canon thread.spawn_indirect ft tbl (core func)) ๐Ÿงต
72
  //         | 0x42 => (canon thread.available_parallelism (core func)) ๐Ÿงต
73
  // async? ::= 0x00 => ฯต
74
  //          | 0x01 => async
75
76
0
  EXPECTED_TRY(uint8_t Flag, FMgr.readByte().map_error(ReportError));
77
0
  auto Code = static_cast<AST::Component::Canonical::OpCode>(Flag);
78
0
  switch (Code) {
79
0
  case AST::Component::Canonical::OpCode::Lift: {
80
0
    EXPECTED_TRY(uint8_t B, FMgr.readByte().map_error(ReportError));
81
0
    if (unlikely(B != 0x00)) {
82
0
      return ReportError(ErrCode::Value::MalformedCanonical);
83
0
    }
84
0
    EXPECTED_TRY(uint32_t Idx, FMgr.readU32().map_error(ReportError));
85
0
    std::vector<AST::Component::CanonOpt> Opts;
86
0
    EXPECTED_TRY(loadVec<AST::Component::Canonical>(
87
0
        Opts, [this](AST::Component::CanonOpt &Opt) {
88
0
          return loadCanonicalOption(Opt);
89
0
        }));
90
0
    EXPECTED_TRY(uint32_t TypeIdx, FMgr.readU32().map_error(ReportError));
91
0
    C.setIndex(Idx);
92
0
    C.setOptions(std::move(Opts));
93
0
    C.setTargetIndex(TypeIdx);
94
0
    break;
95
0
  }
96
0
  case AST::Component::Canonical::OpCode::Lower: {
97
0
    EXPECTED_TRY(auto B, FMgr.readByte().map_error(ReportError));
98
0
    if (unlikely(B != 0x00)) {
99
0
      return ReportError(ErrCode::Value::MalformedCanonical);
100
0
    }
101
0
    EXPECTED_TRY(uint32_t Idx, FMgr.readU32().map_error(ReportError));
102
0
    std::vector<AST::Component::CanonOpt> Opts;
103
0
    EXPECTED_TRY(loadVec<AST::Component::Canonical>(
104
0
        Opts, [this](AST::Component::CanonOpt &Opt) {
105
0
          return loadCanonicalOption(Opt);
106
0
        }));
107
0
    C.setIndex(Idx);
108
0
    C.setOptions(std::move(Opts));
109
0
    break;
110
0
  }
111
0
  case AST::Component::Canonical::OpCode::Resource__new:
112
0
  case AST::Component::Canonical::OpCode::Resource__drop:
113
0
  case AST::Component::Canonical::OpCode::Resource__drop_async:
114
0
  case AST::Component::Canonical::OpCode::Resource__rep:
115
0
  case AST::Component::Canonical::OpCode::Stream__new:
116
0
  case AST::Component::Canonical::OpCode::Stream__close_readable:
117
0
  case AST::Component::Canonical::OpCode::Stream__close_writable:
118
0
  case AST::Component::Canonical::OpCode::Future__new:
119
0
  case AST::Component::Canonical::OpCode::Future__close_readable:
120
0
  case AST::Component::Canonical::OpCode::Future__close_writable:
121
0
  case AST::Component::Canonical::OpCode::Thread__spawn_ref: {
122
0
    EXPECTED_TRY(uint32_t Idx, FMgr.readU32().map_error(ReportError));
123
0
    C.setIndex(Idx);
124
0
    break;
125
0
  }
126
0
  case AST::Component::Canonical::OpCode::Backpressure__set:
127
0
  case AST::Component::Canonical::OpCode::Task__cancel:
128
0
  case AST::Component::Canonical::OpCode::Subtask__drop:
129
0
  case AST::Component::Canonical::OpCode::Error_context__drop:
130
0
  case AST::Component::Canonical::OpCode::Waitable_set__new:
131
0
  case AST::Component::Canonical::OpCode::Waitable_set__drop:
132
0
  case AST::Component::Canonical::OpCode::Waitable__join:
133
0
    break;
134
0
  default:
135
0
    return ReportError(ErrCode::Value::MalformedCanonical);
136
0
  }
137
0
  C.setOpCode(Code);
138
0
  return {};
139
0
}
140
141
0
Expect<void> Loader::loadCanonicalOption(AST::Component::CanonOpt &Opt) {
142
0
  auto ReportError = [this](auto E) {
143
0
    return logLoadError(E, FMgr.getLastOffset(), ASTNodeAttr::Comp_CanonOpt);
144
0
  };
Unexecuted instantiation: component_canonical.cpp:auto WasmEdge::Loader::Loader::loadCanonicalOption(WasmEdge::AST::Component::CanonOpt&)::$_0::operator()<WasmEdge::ErrCode>(WasmEdge::ErrCode) const
Unexecuted instantiation: component_canonical.cpp:auto WasmEdge::Loader::Loader::loadCanonicalOption(WasmEdge::AST::Component::CanonOpt&)::$_0::operator()<WasmEdge::ErrCode::Value>(WasmEdge::ErrCode::Value) const
145
  // canonopt ::= 0x00                  => string-encoding=utf8
146
  //            | 0x01                  => string-encoding=utf16
147
  //            | 0x02                  => string-encoding=latin1+utf16
148
  //            | 0x03 m:<core:memidx>  => (memory m)
149
  //            | 0x04 f:<core:funcidx> => (realloc f)
150
  //            | 0x05 f:<core:funcidx> => (post-return f)
151
  //            | 0x06                  => async ๐Ÿ”€
152
  //            | 0x07 f:<core:funcidx> => (callback f) ๐Ÿ”€
153
  //            | 0x08                  => always-task-return ๐Ÿ”€
154
155
0
  EXPECTED_TRY(uint8_t Flag, FMgr.readByte().map_error(ReportError));
156
0
  switch (Flag) {
157
0
  case 0x00:
158
0
  case 0x01:
159
0
  case 0x02:
160
0
  case 0x06:
161
0
  case 0x08:
162
0
    break;
163
0
  case 0x03:
164
0
  case 0x04:
165
0
  case 0x05:
166
0
  case 0x07: {
167
0
    EXPECTED_TRY(uint32_t Idx, FMgr.readU32().map_error(ReportError));
168
0
    Opt.setIndex(Idx);
169
0
    break;
170
0
  }
171
0
  default:
172
0
    return ReportError(ErrCode::Value::UnknownCanonicalOption);
173
0
  }
174
0
  Opt.setCode(static_cast<AST::Component::CanonOpt::OptCode>(Flag));
175
0
  return {};
176
0
}
177
178
} // namespace Loader
179
} // namespace WasmEdge