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