Coverage Report

Created: 2026-11-12 06:35

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
#include "common/component_valtype.h"
18
19
#include <variant>
20
21
namespace WasmEdge {
22
namespace AST {
23
namespace Component {
24
25
/// NOTE: The `ImportDesc` in AST implements the full import with name and
26
/// module name in one class. Therefore, create a `CoreImportDesc` class with
27
/// only the import descriptions for the component model.
28
29
/// AST Component::CoreImportDesc node.
30
class CoreImportDesc {
31
public:
32
292
  uint32_t getTypeIndex() const noexcept {
33
292
    return *std::get_if<uint32_t>(&Type);
34
292
  }
35
2.66k
  void setTypeIndex(const uint32_t Idx) noexcept {
36
2.66k
    Type.emplace<uint32_t>(Idx);
37
2.66k
  }
38
39
99
  const TableType &getTableType() const noexcept {
40
99
    return *std::get_if<TableType>(&Type);
41
99
  }
42
264
  void setTableType(TableType &&TT) noexcept {
43
264
    Type.emplace<TableType>(std::move(TT));
44
264
  }
45
46
1.78k
  const MemoryType &getMemoryType() const noexcept {
47
1.78k
    return *std::get_if<MemoryType>(&Type);
48
1.78k
  }
49
1.05k
  void setMemoryType(MemoryType &&MT) noexcept {
50
1.05k
    Type.emplace<MemoryType>(std::move(MT));
51
1.05k
  }
52
53
86
  const GlobalType &getGlobalType() const noexcept {
54
86
    return *std::get_if<GlobalType>(&Type);
55
86
  }
56
213
  void setGlobalType(GlobalType &&GT) noexcept {
57
213
    Type.emplace<GlobalType>(std::move(GT));
58
213
  }
59
60
37
  const TagType &getTagType() const noexcept {
61
37
    return *std::get_if<TagType>(&Type);
62
37
  }
63
236
  void setTagType(TagType &&TT) noexcept {
64
236
    Type.emplace<TagType>(std::move(TT));
65
236
  }
66
67
  /// The kind of core extern the descriptor describes.
68
1.29k
  ExternalType getExternalType() const noexcept {
69
1.29k
    if (std::holds_alternative<TableType>(Type)) {
70
51
      return ExternalType::Table;
71
51
    }
72
1.23k
    if (std::holds_alternative<MemoryType>(Type)) {
73
895
      return ExternalType::Memory;
74
895
    }
75
344
    if (std::holds_alternative<GlobalType>(Type)) {
76
45
      return ExternalType::Global;
77
45
    }
78
299
    if (std::holds_alternative<TagType>(Type)) {
79
37
      return ExternalType::Tag;
80
37
    }
81
262
    return ExternalType::Function;
82
299
  }
83
84
private:
85
  std::variant<uint32_t, TableType, MemoryType, GlobalType, TagType> Type;
86
};
87
88
/// FROM:
89
/// https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#type-checking
90
///
91
/// When we next consider type imports and exports, there are two distinct
92
/// subcases of typebound to consider: eq and sub.
93
///
94
/// The eq bound adds a type equality rule (extending the built-in set of
95
/// subtyping rules) saying that the imported type is structurally equivalent to
96
/// the type referenced in the bound.
97
///
98
/// In contrast, the sub bound introduces a new abstract type which the rest of
99
/// the component must conservatively assume can be any type that is a subtype
100
/// of the bound. What this means for type-checking is that each subtype-bound
101
/// type import/export introduces a fresh abstract type that is unequal to every
102
/// preceding type definition.
103
///
104
/// NOTE:
105
/// Think of Java's `? extends T`.
106
///
107
/// 1. optional `some i` as `(eq i)`
108
/// 2. optional `none` as `sub`, i.e. Subresource
109
110
// externdesc ::= 0x00 0x11 i:<core:typeidx> => (core module (type i))
111
//              | 0x01 i:<typeidx>           => (func (type i))
112
//              | 0x02 b:<valuebound>        => (value b) 🪙
113
//              | 0x03 b:<typebound>         => (type b)
114
//              | 0x04 i:<typeidx>           => (component (type i))
115
//              | 0x05 i:<typeidx>           => (instance (type i))
116
// valuebound ::= 0x00 i:<valueidx>          => (eq i) 🪙
117
//              | 0x01 t:<valtype>           => t 🪙
118
// typebound  ::= 0x00 i:<typeidx>           => (eq i)
119
//              | 0x01                       => (sub resource)
120
121
class ExternDesc {
122
public:
123
  enum class DescType : uint8_t {
124
    CoreType = 0x00,
125
    FuncType = 0x01,
126
    ValueBound = 0x02,
127
    TypeBound = 0x03,
128
    ComponentType = 0x04,
129
    InstanceType = 0x05,
130
  };
131
132
8.87k
  DescType getDescType() const noexcept { return Type; }
133
1.74k
  uint32_t getTypeIndex() const noexcept { return Idx; }
134
8.14k
  bool isEqType() const noexcept { return Eq; }
135
1.21k
  const ComponentValType &getValType() const noexcept { return VType; }
136
137
172
  void setCoreTypeIdx(const uint32_t I) noexcept {
138
172
    Type = DescType::CoreType;
139
172
    Idx = I;
140
172
  }
141
1.52k
  void setFuncTypeIdx(const uint32_t I) noexcept {
142
1.52k
    Type = DescType::FuncType;
143
1.52k
    Idx = I;
144
1.52k
  }
145
158
  void setValueBound(const uint32_t I) noexcept {
146
158
    Type = DescType::ValueBound;
147
158
    Eq = true;
148
158
    Idx = I;
149
158
  }
150
1.20k
  void setValueBound(const ComponentValType &T) noexcept {
151
1.20k
    Type = DescType::ValueBound;
152
1.20k
    Eq = false;
153
1.20k
    VType = T;
154
1.20k
  }
155
971
  void setTypeBound(const uint32_t I) noexcept {
156
971
    Type = DescType::TypeBound;
157
971
    Eq = true;
158
971
    Idx = I;
159
971
  }
160
7.23k
  void setTypeBound() noexcept {
161
7.23k
    Type = DescType::TypeBound;
162
7.23k
    Eq = false;
163
7.23k
  }
164
533
  void setComponentTypeIdx(const uint32_t I) noexcept {
165
533
    Type = DescType::ComponentType;
166
533
    Idx = I;
167
533
  }
168
348
  void setInstanceTypeIdx(const uint32_t I) noexcept {
169
348
    Type = DescType::InstanceType;
170
348
    Idx = I;
171
348
  }
172
173
private:
174
  DescType Type;
175
  bool Eq;
176
  uint32_t Idx;
177
  ComponentValType VType;
178
};
179
180
} // namespace Component
181
} // namespace AST
182
} // namespace WasmEdge