/src/WasmEdge/include/ast/component/descriptor.h
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // SPDX-FileCopyrightText: 2019-2025 Second State INC |
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/component/valtype.h" |
17 | | #include "ast/type.h" |
18 | | |
19 | | #include <variant> |
20 | | |
21 | | namespace WasmEdge { |
22 | | namespace AST { |
23 | | namespace Component { |
24 | | |
25 | | /// NOTE: The `ImportDesc` in AST implemented the fully import with name and |
26 | | /// module name in a class. Therefore create a `CoreImportDesc` class with |
27 | | /// only the import descriptions for component model. |
28 | | |
29 | | /// AST Component::CoreImportDesc node. |
30 | | class CoreImportDesc { |
31 | | public: |
32 | 0 | uint32_t getTypeIndex() const noexcept { |
33 | 0 | return *std::get_if<uint32_t>(&Type); |
34 | 0 | } |
35 | 0 | void setTypeIndex(const uint32_t Idx) noexcept { |
36 | 0 | Type.emplace<uint32_t>(Idx); |
37 | 0 | } |
38 | | |
39 | 0 | const TableType &getTableType() const noexcept { |
40 | 0 | return *std::get_if<TableType>(&Type); |
41 | 0 | } |
42 | 0 | void setTableType(TableType &&TT) noexcept { |
43 | 0 | Type.emplace<TableType>(std::move(TT)); |
44 | 0 | } |
45 | | |
46 | 0 | const MemoryType &getMemoryType() const noexcept { |
47 | 0 | return *std::get_if<MemoryType>(&Type); |
48 | 0 | } |
49 | 0 | void setMemoryType(MemoryType &&MT) noexcept { |
50 | 0 | Type.emplace<MemoryType>(std::move(MT)); |
51 | 0 | } |
52 | | |
53 | 0 | const GlobalType &getGlobalType() const noexcept { |
54 | 0 | return *std::get_if<GlobalType>(&Type); |
55 | 0 | } |
56 | 0 | void setGlobalType(GlobalType &>) noexcept { |
57 | 0 | Type.emplace<GlobalType>(std::move(GT)); |
58 | 0 | } |
59 | | |
60 | 0 | const TagType &getTagType() const noexcept { |
61 | 0 | return *std::get_if<TagType>(&Type); |
62 | 0 | } |
63 | 0 | void setTagType(TagType &&TT) noexcept { |
64 | 0 | Type.emplace<TagType>(std::move(TT)); |
65 | 0 | } |
66 | | |
67 | | private: |
68 | | std::variant<uint32_t, TableType, MemoryType, GlobalType, TagType> Type; |
69 | | }; |
70 | | |
71 | | /// FROM: |
72 | | /// https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#type-checking |
73 | | /// |
74 | | /// When we next consider type imports and exports, there are two distinct |
75 | | /// subcases of typebound to consider: eq and sub. |
76 | | /// |
77 | | /// The eq bound adds a type equality rule (extending the built-in set of |
78 | | /// subtyping rules) saying that the imported type is structurally equivalent to |
79 | | /// the type referenced in the bound. |
80 | | /// |
81 | | /// In contrast, the sub bound introduces a new abstract type which the rest of |
82 | | /// the component must conservatively assume can be any type that is a subtype |
83 | | /// of the bound. What this means for type-checking is that each subtype-bound |
84 | | /// type import/export introduces a fresh abstract type that is unequal to every |
85 | | /// preceding type definition. |
86 | | /// |
87 | | /// NOTE: |
88 | | /// One just need to consider Java's `? extends T` in mind. |
89 | | /// |
90 | | /// 1. optional `some i` as `(eq i)` |
91 | | /// 2. optional `none` as `sub`, i.e. Subresource |
92 | | |
93 | | // externdesc ::= 0x00 0x11 i:<core:typeidx> => (core module (type i)) |
94 | | // | 0x01 i:<typeidx> => (func (type i)) |
95 | | // | 0x02 b:<valuebound> => (value b) 🪙 |
96 | | // | 0x03 b:<typebound> => (type b) |
97 | | // | 0x04 i:<typeidx> => (component (type i)) |
98 | | // | 0x05 i:<typeidx> => (instance (type i)) |
99 | | // valuebound ::= 0x00 i:<valueidx> => (eq i) 🪙 |
100 | | // | 0x01 t:<valtype> => t 🪙 |
101 | | // typebound ::= 0x00 i:<typeidx> => (eq i) |
102 | | // | 0x01 => (sub resource) |
103 | | |
104 | | class ExternDesc { |
105 | | public: |
106 | | enum class DescType : Byte { |
107 | | CoreType = 0x00, |
108 | | FuncType = 0x01, |
109 | | ValueBound = 0x02, |
110 | | TypeBound = 0x03, |
111 | | ComponentType = 0x04, |
112 | | InstanceType = 0x05, |
113 | | }; |
114 | | |
115 | 0 | DescType getDescType() const noexcept { return Type; } |
116 | 0 | uint32_t getTypeIndex() const noexcept { return Idx; } |
117 | 0 | bool isEqType() const noexcept { return Eq; } |
118 | 0 | const ValueType &getValueType() const noexcept { return VType; } |
119 | | |
120 | 0 | void setCoreTypeIdx(const uint32_t I) noexcept { |
121 | 0 | Type = DescType::CoreType; |
122 | 0 | Idx = I; |
123 | 0 | } |
124 | 0 | void setFuncTypeIdx(const uint32_t I) noexcept { |
125 | 0 | Type = DescType::FuncType; |
126 | 0 | Idx = I; |
127 | 0 | } |
128 | 0 | void setValueBound(const uint32_t I) noexcept { |
129 | 0 | Type = DescType::ValueBound; |
130 | 0 | Eq = true; |
131 | 0 | Idx = I; |
132 | 0 | } |
133 | 0 | void setValueBound(const ValueType &T) noexcept { |
134 | 0 | Type = DescType::ValueBound; |
135 | 0 | Eq = false; |
136 | 0 | VType = T; |
137 | 0 | } |
138 | 0 | void setTypeBound(const uint32_t I) noexcept { |
139 | 0 | Type = DescType::TypeBound; |
140 | 0 | Eq = true; |
141 | 0 | Idx = I; |
142 | 0 | } |
143 | 0 | void setTypeBound() noexcept { |
144 | 0 | Type = DescType::TypeBound; |
145 | 0 | Eq = false; |
146 | 0 | } |
147 | 0 | void setComponentTypeIdx(const uint32_t I) noexcept { |
148 | 0 | Type = DescType::ComponentType; |
149 | 0 | Idx = I; |
150 | 0 | } |
151 | 0 | void setInstanceTypeIdx(const uint32_t I) noexcept { |
152 | 0 | Type = DescType::InstanceType; |
153 | 0 | Idx = I; |
154 | 0 | } |
155 | | |
156 | | private: |
157 | | DescType Type; |
158 | | bool Eq; |
159 | | uint32_t Idx; |
160 | | ValueType VType; |
161 | | }; |
162 | | |
163 | | } // namespace Component |
164 | | } // namespace AST |
165 | | } // namespace WasmEdge |