Coverage Report

Created: 2026-07-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/ast/component/descriptor.h
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
//===-- wasmedge/ast/component/descriptor.h - Descriptor class definitions ===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contains the declaration of the Descriptor related class.
12
///
13
//===----------------------------------------------------------------------===//
14
#pragma once
15
16
#include "ast/type.h"
17
18
#include <variant>
19
20
namespace WasmEdge {
21
namespace AST {
22
namespace Component {
23
24
/// NOTE: The `ImportDesc` in AST implements the full import with name and
25
/// module name in one class. Therefore, create a `CoreImportDesc` class with
26
/// only the import descriptions for the component model.
27
28
/// AST Component::CoreImportDesc node.
29
class CoreImportDesc {
30
public:
31
35
  uint32_t getTypeIndex() const noexcept {
32
35
    return *std::get_if<uint32_t>(&Type);
33
35
  }
34
4.77k
  void setTypeIndex(const uint32_t Idx) noexcept {
35
4.77k
    Type.emplace<uint32_t>(Idx);
36
4.77k
  }
37
38
0
  const TableType &getTableType() const noexcept {
39
0
    return *std::get_if<TableType>(&Type);
40
0
  }
41
181
  void setTableType(TableType &&TT) noexcept {
42
181
    Type.emplace<TableType>(std::move(TT));
43
181
  }
44
45
0
  const MemoryType &getMemoryType() const noexcept {
46
0
    return *std::get_if<MemoryType>(&Type);
47
0
  }
48
264
  void setMemoryType(MemoryType &&MT) noexcept {
49
264
    Type.emplace<MemoryType>(std::move(MT));
50
264
  }
51
52
0
  const GlobalType &getGlobalType() const noexcept {
53
0
    return *std::get_if<GlobalType>(&Type);
54
0
  }
55
697
  void setGlobalType(GlobalType &&GT) noexcept {
56
697
    Type.emplace<GlobalType>(std::move(GT));
57
697
  }
58
59
0
  const TagType &getTagType() const noexcept {
60
0
    return *std::get_if<TagType>(&Type);
61
0
  }
62
255
  void setTagType(TagType &&TT) noexcept {
63
255
    Type.emplace<TagType>(std::move(TT));
64
255
  }
65
66
733
  bool isFunc() const noexcept {
67
733
    return std::holds_alternative<uint32_t>(Type);
68
733
  }
69
698
  bool isTable() const noexcept {
70
698
    return std::holds_alternative<TableType>(Type);
71
698
  }
72
563
  bool isMemory() const noexcept {
73
563
    return std::holds_alternative<MemoryType>(Type);
74
563
  }
75
326
  bool isGlobal() const noexcept {
76
326
    return std::holds_alternative<GlobalType>(Type);
77
326
  }
78
20
  bool isTag() const noexcept { return std::holds_alternative<TagType>(Type); }
79
80
private:
81
  std::variant<uint32_t, TableType, MemoryType, GlobalType, TagType> Type;
82
};
83
84
/// FROM:
85
/// https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#type-checking
86
///
87
/// When we next consider type imports and exports, there are two distinct
88
/// subcases of typebound to consider: eq and sub.
89
///
90
/// The eq bound adds a type equality rule (extending the built-in set of
91
/// subtyping rules) saying that the imported type is structurally equivalent to
92
/// the type referenced in the bound.
93
///
94
/// In contrast, the sub bound introduces a new abstract type which the rest of
95
/// the component must conservatively assume can be any type that is a subtype
96
/// of the bound. What this means for type-checking is that each subtype-bound
97
/// type import/export introduces a fresh abstract type that is unequal to every
98
/// preceding type definition.
99
///
100
/// NOTE:
101
/// Think of Java's `? extends T`.
102
///
103
/// 1. optional `some i` as `(eq i)`
104
/// 2. optional `none` as `sub`, i.e. Subresource
105
106
// externdesc ::= 0x00 0x11 i:<core:typeidx> => (core module (type i))
107
//              | 0x01 i:<typeidx>           => (func (type i))
108
//              | 0x02 b:<valuebound>        => (value b) 🪙
109
//              | 0x03 b:<typebound>         => (type b)
110
//              | 0x04 i:<typeidx>           => (component (type i))
111
//              | 0x05 i:<typeidx>           => (instance (type i))
112
// valuebound ::= 0x00 i:<valueidx>          => (eq i) 🪙
113
//              | 0x01 t:<valtype>           => t 🪙
114
// typebound  ::= 0x00 i:<typeidx>           => (eq i)
115
//              | 0x01                       => (sub resource)
116
117
class ExternDesc {
118
public:
119
  enum class DescType : uint8_t {
120
    CoreType = 0x00,
121
    FuncType = 0x01,
122
    ValueBound = 0x02,
123
    TypeBound = 0x03,
124
    ComponentType = 0x04,
125
    InstanceType = 0x05,
126
  };
127
128
13.3k
  DescType getDescType() const noexcept { return Type; }
129
1.19k
  uint32_t getTypeIndex() const noexcept { return Idx; }
130
1.26k
  bool isEqType() const noexcept { return Eq; }
131
0
  const ComponentValType &getValType() const noexcept { return VType; }
132
133
235
  void setCoreTypeIdx(const uint32_t I) noexcept {
134
235
    Type = DescType::CoreType;
135
235
    Idx = I;
136
235
  }
137
1.04k
  void setFuncTypeIdx(const uint32_t I) noexcept {
138
1.04k
    Type = DescType::FuncType;
139
1.04k
    Idx = I;
140
1.04k
  }
141
1.71k
  void setValueBound(const uint32_t I) noexcept {
142
1.71k
    Type = DescType::ValueBound;
143
1.71k
    Eq = true;
144
1.71k
    Idx = I;
145
1.71k
  }
146
1.77k
  void setValueBound(const ComponentValType &T) noexcept {
147
1.77k
    Type = DescType::ValueBound;
148
1.77k
    Eq = false;
149
1.77k
    VType = T;
150
1.77k
  }
151
118
  void setTypeBound(const uint32_t I) noexcept {
152
118
    Type = DescType::TypeBound;
153
118
    Eq = true;
154
118
    Idx = I;
155
118
  }
156
1.78k
  void setTypeBound() noexcept {
157
1.78k
    Type = DescType::TypeBound;
158
1.78k
    Eq = false;
159
1.78k
  }
160
957
  void setComponentTypeIdx(const uint32_t I) noexcept {
161
957
    Type = DescType::ComponentType;
162
957
    Idx = I;
163
957
  }
164
417
  void setInstanceTypeIdx(const uint32_t I) noexcept {
165
417
    Type = DescType::InstanceType;
166
417
    Idx = I;
167
417
  }
168
169
private:
170
  DescType Type;
171
  bool Eq;
172
  uint32_t Idx;
173
  ComponentValType VType;
174
};
175
176
} // namespace Component
177
} // namespace AST
178
} // namespace WasmEdge