Coverage Report

Created: 2026-09-28 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/thirdparty/wasm/wasm.hh
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WebAssembly wasm-c-api Authors
3
4
// Vendored verbatim from the WebAssembly C API proposal:
5
// <https://github.com/WebAssembly/wasm-c-api/blob/9d6b93764ac96cdd9db51081c363e09d2d488b4d/include/wasm.hh>
6
//
7
// Do not edit this file in-tree. Update it by re-copying the header from a
8
// newer upstream revision.
9
10
// WebAssembly C++ API
11
12
#ifndef WASM_HH
13
#define WASM_HH
14
15
#include <cassert>
16
#include <cstddef>
17
#include <cstdint>
18
#include <cstring>
19
#include <memory>
20
#include <new>
21
#include <limits>
22
#include <string>
23
24
#ifndef WASM_API_EXTERN
25
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(LIBWASM_STATIC)
26
#define WASM_API_EXTERN __declspec(dllimport)
27
#else
28
#define WASM_API_EXTERN
29
#endif
30
#endif
31
32
33
///////////////////////////////////////////////////////////////////////////////
34
// Auxiliaries
35
36
// Machine types
37
38
static_assert(sizeof(float) == sizeof(int32_t), "incompatible float type");
39
static_assert(sizeof(double) == sizeof(int64_t), "incompatible double type");
40
static_assert(sizeof(intptr_t) == sizeof(int32_t) ||
41
              sizeof(intptr_t) == sizeof(int64_t), "incompatible pointer type");
42
43
using byte_t = char;
44
using float32_t = float;
45
using float64_t = double;
46
47
48
namespace wasm {
49
50
// Vectors
51
52
template<class T>
53
class vec {
54
  static const size_t invalid_size = SIZE_MAX;
55
56
  size_t size_;
57
  std::unique_ptr<T[]> data_;
58
59
#ifdef WASM_API_DEBUG
60
  WASM_API_EXTERN void make_data();
61
  WASM_API_EXTERN void free_data();
62
#else
63
0
  void make_data() {}
Unexecuted instantiation: wasm::vec<char>::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<wasm::Val>::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::make_data()
Unexecuted instantiation: wasm::vec<wasm::Extern*>::make_data()
64
0
  void free_data() {}
Unexecuted instantiation: wasm::vec<char>::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<wasm::Val>::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::free_data()
Unexecuted instantiation: wasm::vec<wasm::Extern*>::free_data()
65
#endif
66
67
0
  vec(size_t size) : vec(size, size ? new(std::nothrow) T[size] : nullptr) {
68
0
    make_data();
69
0
  }
Unexecuted instantiation: wasm::vec<char>::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<wasm::Val>::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::vec(unsigned long)
Unexecuted instantiation: wasm::vec<wasm::Extern*>::vec(unsigned long)
70
71
0
  vec(size_t size, T* data) : size_(size), data_(data) {
72
0
    assert(!!size_ == !!data_ || size_ == invalid_size);
73
0
  }
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::ValType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<char>::vec(unsigned long, char*)
Unexecuted instantiation: wasm::vec<wasm::Val>::vec(unsigned long, wasm::Val*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::FuncType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::TableType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::TagType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::ExternType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::ImportType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::ExportType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::Frame, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::vec(unsigned long, std::__1::unique_ptr<wasm::Extern, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<wasm::Extern*>::vec(unsigned long, wasm::Extern**)
74
75
public:
76
  using elem_type = T;
77
78
0
  vec(vec<T>&& that) : vec(that.size_, that.data_.release()) {
79
0
    that.size_ = invalid_size;
80
0
  }
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::vec(wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >&&)
Unexecuted instantiation: wasm::vec<char>::vec(wasm::vec<char>&&)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::vec(wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >&&)
81
82
0
  ~vec() {
83
0
    free_data();
84
0
  }
Unexecuted instantiation: wasm::vec<char>::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<wasm::Val>::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::~vec()
Unexecuted instantiation: wasm::vec<wasm::Extern*>::~vec()
85
86
0
  operator bool() const {
87
0
    return bool(size_ != invalid_size);
88
0
  }
Unexecuted instantiation: wasm::vec<char>::operator bool() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::operator bool() const
89
90
0
  auto size() const -> size_t {
91
0
    return size_;
92
0
  }
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<char>::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<wasm::Val>::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::size() const
Unexecuted instantiation: wasm::vec<wasm::Extern*>::size() const
93
94
0
  auto get() const -> const T* {
95
0
    return data_.get();
96
0
  }
97
98
0
  auto get() -> T* {
99
0
    return data_.get();
100
0
  }
101
102
0
  auto release() -> T* {
103
0
    size_ = invalid_size;
104
0
    return data_.release();
105
0
  }
Unexecuted instantiation: wasm::vec<char>::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<wasm::Val>::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::release()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::release()
106
107
  void reset() {
108
    free_data();
109
    size_ = invalid_size;
110
    data_.reset();
111
  }
112
113
0
  void reset(vec& that) {
114
0
    free_data();
115
0
    size_ = that.size_;
116
0
    data_.reset(that.data_.release());
117
0
    that.size_ = invalid_size;
118
0
  }
119
120
0
  auto operator=(vec&& that) -> vec& {
121
0
    reset(that);
122
0
    return *this;
123
0
  }
124
125
0
  auto operator[](size_t i) -> T& {
126
0
    assert(i < size_);
127
0
    return data_[i];
128
0
  }
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<wasm::Val>::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::operator[](unsigned long)
Unexecuted instantiation: wasm::vec<wasm::Extern*>::operator[](unsigned long)
129
130
0
  auto operator[](size_t i) const -> const T& {
131
0
    assert(i < size_);
132
0
    return data_[i];
133
0
  }
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::operator[](unsigned long) const
Unexecuted instantiation: wasm::vec<wasm::Val>::operator[](unsigned long) const
Unexecuted instantiation: wasm::vec<wasm::Extern*>::operator[](unsigned long) const
134
135
0
  auto copy() const -> vec {
136
0
    auto v = vec(size_);
137
0
    if (v) for (size_t i = 0; i < size_; ++i) v.data_[i] = data_[i];
138
0
    return v;
139
0
  }
140
141
  // TODO: This can't be used for e.g. vec<Val>
142
0
  auto deep_copy() const -> vec {
143
0
    auto v = vec(size_);
144
0
    if (v) for (size_t i = 0; i < size_; ++i) v.data_[i] = data_[i]->copy();
145
0
    return v;
146
0
  }
147
148
0
  static auto make_uninitialized(size_t size = 0) -> vec {
149
0
    return vec(size);
150
0
  }
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<wasm::Val>::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<char>::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::make_uninitialized(unsigned long)
Unexecuted instantiation: wasm::vec<wasm::Extern*>::make_uninitialized(unsigned long)
151
152
  static auto make(size_t size, T init[]) -> vec {
153
    auto v = vec(size);
154
    if (v) for (size_t i = 0; i < size; ++i) v.data_[i] = std::move(init[i]);
155
    return v;
156
  }
157
158
0
  static auto make(std::string s) -> vec<char> {
159
0
    auto v = vec(s.length());
160
0
    if (v) std::strncpy(v.get(), s.data(), s.length());
161
0
    return v;
162
0
  }
163
164
0
  static auto make_nt(std::string s) -> vec<char> {
165
0
    auto v = vec(s.length() + 1);
166
0
    if (v) std::strcpy(v.get(), s.data());
167
0
    return v;
168
0
  }
169
170
  // TODO(mvsc): MVSC requires this special case:
171
0
  static auto make() -> vec {
172
0
    return vec(0);
173
0
  }
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::make()
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::make()
174
175
  template<class... Ts>
176
  static auto make(Ts&&... args) -> vec {
177
    T data[] = { std::forward<Ts>(args)... };
178
    return make(sizeof...(Ts), data);
179
  }
180
181
0
  static auto adopt(size_t size, T data[]) -> vec {
182
0
    return vec(size, data);
183
0
  }
Unexecuted instantiation: wasm::vec<char>::adopt(unsigned long, char*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ValType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::ValType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::FuncType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::FuncType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::GlobalType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TableType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::TableType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::MemoryType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::TagType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::TagType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExternType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::ExternType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ImportType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::ImportType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::ExportType, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::ExportType, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<wasm::Val>::adopt(unsigned long, wasm::Val*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Frame, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::Frame, wasm::destroyer>*)
Unexecuted instantiation: wasm::vec<std::__1::unique_ptr<wasm::Extern, wasm::destroyer> >::adopt(unsigned long, std::__1::unique_ptr<wasm::Extern, wasm::destroyer>*)
184
185
  static auto invalid() -> vec {
186
    return vec(invalid_size, nullptr);
187
  }
188
};
189
190
191
// Ownership
192
193
class destroyer {
194
public:
195
  template <typename T>
196
0
  void operator()(T* ptr) {
197
0
    ptr->destroy();
198
0
  }
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Ref>(wasm::Ref*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::ValType>(wasm::ValType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::FuncType>(wasm::FuncType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::GlobalType>(wasm::GlobalType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::TableType>(wasm::TableType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::MemoryType>(wasm::MemoryType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::TagType>(wasm::TagType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Trap>(wasm::Trap*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Config>(wasm::Config*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::ExternType>(wasm::ExternType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_trap_t>(wasm_trap_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_ref_t>(wasm_ref_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Engine>(wasm::Engine*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Store>(wasm::Store*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_valtype_t>(wasm_valtype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_functype_t>(wasm_functype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_globaltype_t>(wasm_globaltype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_tabletype_t>(wasm_tabletype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_memorytype_t>(wasm_memorytype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_tagtype_t>(wasm_tagtype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_externtype_t>(wasm_externtype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::ImportType>(wasm::ImportType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_importtype_t>(wasm_importtype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::ExportType>(wasm::ExportType*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_exporttype_t>(wasm_exporttype_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Frame>(wasm::Frame*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_frame_t>(wasm_frame_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Foreign>(wasm::Foreign*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Module>(wasm::Module*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Shared<wasm::Module> >(wasm::Shared<wasm::Module>*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Func>(wasm::Func*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Global>(wasm::Global*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Table>(wasm::Table*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Memory>(wasm::Memory*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Extern>(wasm::Extern*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_extern_t>(wasm_extern_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm::Instance>(wasm::Instance*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_config_t>(wasm_config_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_engine_t>(wasm_engine_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_store_t>(wasm_store_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_foreign_t>(wasm_foreign_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_module_t>(wasm_module_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_shared_module_t>(wasm_shared_module_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_func_t>(wasm_func_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_global_t>(wasm_global_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_table_t>(wasm_table_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_memory_t>(wasm_memory_t*)
Unexecuted instantiation: void wasm::destroyer::operator()<wasm_instance_t>(wasm_instance_t*)
199
};
200
201
template<class T> using own = std::unique_ptr<T, destroyer>;
202
template<class T> using ownvec = vec<own<T>>;
203
204
0
template<class T> own<T> make_own(T* ptr) {
205
0
  return own<T>(ptr);
206
0
}
Unexecuted instantiation: std::__1::unique_ptr<wasm_trap_t, wasm::destroyer> wasm::make_own<wasm_trap_t>(wasm_trap_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm::Config, wasm::destroyer> wasm::make_own<wasm::Config>(wasm::Config*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_valtype_t, wasm::destroyer> wasm::make_own<wasm_valtype_t>(wasm_valtype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_functype_t, wasm::destroyer> wasm::make_own<wasm_functype_t>(wasm_functype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_globaltype_t, wasm::destroyer> wasm::make_own<wasm_globaltype_t>(wasm_globaltype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_tabletype_t, wasm::destroyer> wasm::make_own<wasm_tabletype_t>(wasm_tabletype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_memorytype_t, wasm::destroyer> wasm::make_own<wasm_memorytype_t>(wasm_memorytype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_tagtype_t, wasm::destroyer> wasm::make_own<wasm_tagtype_t>(wasm_tagtype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_externtype_t, wasm::destroyer> wasm::make_own<wasm_externtype_t>(wasm_externtype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_importtype_t, wasm::destroyer> wasm::make_own<wasm_importtype_t>(wasm_importtype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_exporttype_t, wasm::destroyer> wasm::make_own<wasm_exporttype_t>(wasm_exporttype_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_ref_t, wasm::destroyer> wasm::make_own<wasm_ref_t>(wasm_ref_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_frame_t, wasm::destroyer> wasm::make_own<wasm_frame_t>(wasm_frame_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_extern_t, wasm::destroyer> wasm::make_own<wasm_extern_t>(wasm_extern_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_config_t, wasm::destroyer> wasm::make_own<wasm_config_t>(wasm_config_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_engine_t, wasm::destroyer> wasm::make_own<wasm_engine_t>(wasm_engine_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_store_t, wasm::destroyer> wasm::make_own<wasm_store_t>(wasm_store_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_foreign_t, wasm::destroyer> wasm::make_own<wasm_foreign_t>(wasm_foreign_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_module_t, wasm::destroyer> wasm::make_own<wasm_module_t>(wasm_module_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_shared_module_t, wasm::destroyer> wasm::make_own<wasm_shared_module_t>(wasm_shared_module_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_func_t, wasm::destroyer> wasm::make_own<wasm_func_t>(wasm_func_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_global_t, wasm::destroyer> wasm::make_own<wasm_global_t>(wasm_global_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_table_t, wasm::destroyer> wasm::make_own<wasm_table_t>(wasm_table_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_memory_t, wasm::destroyer> wasm::make_own<wasm_memory_t>(wasm_memory_t*)
Unexecuted instantiation: std::__1::unique_ptr<wasm_instance_t, wasm::destroyer> wasm::make_own<wasm_instance_t>(wasm_instance_t*)
207
208
///////////////////////////////////////////////////////////////////////////////
209
// Runtime Environment
210
211
// Configuration
212
213
class WASM_API_EXTERN Config {
214
  friend class destroyer;
215
  void destroy();
216
217
protected:
218
  Config() = default;
219
  ~Config() = default;
220
221
public:
222
  static auto make() -> own<Config>;
223
224
  // Implementations may provide custom methods for manipulating Configs.
225
};
226
227
228
// Engine
229
230
class WASM_API_EXTERN Engine {
231
  friend class destroyer;
232
  void destroy();
233
234
protected:
235
  Engine() = default;
236
  ~Engine() = default;
237
238
public:
239
  static auto make(own<Config>&& = Config::make()) -> own<Engine>;
240
};
241
242
243
// Store
244
245
class WASM_API_EXTERN Store {
246
  friend class destroyer;
247
  void destroy();
248
249
protected:
250
  Store() = default;
251
  ~Store() = default;
252
253
public:
254
  static auto make(Engine*) -> own<Store>;
255
};
256
257
258
///////////////////////////////////////////////////////////////////////////////
259
// Type Representations
260
261
// Type attributes
262
263
enum class Mutability : uint8_t { CONST, VAR };
264
265
struct Limits {
266
  uint32_t min;
267
  uint32_t max;
268
269
  Limits(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max()) :
270
0
    min(min), max(max) {}
271
};
272
273
274
// Value Types
275
276
enum class ValKind : uint8_t {
277
  I32, I64, F32, F64,
278
  EXTERNREF = 128, FUNCREF,
279
};
280
281
0
inline bool is_num(ValKind k) { return k < ValKind::EXTERNREF; }
282
0
inline bool is_ref(ValKind k) { return k >= ValKind::EXTERNREF; }
283
284
285
class WASM_API_EXTERN ValType {
286
  friend class destroyer;
287
  void destroy();
288
289
protected:
290
  ValType() = default;
291
  ~ValType() = default;
292
293
public:
294
  static auto make(ValKind) -> own<ValType>;
295
  auto copy() const -> own<ValType>;
296
297
  auto kind() const -> ValKind;
298
0
  auto is_num() const -> bool { return wasm::is_num(kind()); }
299
0
  auto is_ref() const -> bool { return wasm::is_ref(kind()); }
300
};
301
302
303
// External Types
304
305
enum class ExternKind : uint8_t {
306
  FUNC, GLOBAL, TABLE, MEMORY, TAG
307
};
308
309
class FuncType;
310
class GlobalType;
311
class TableType;
312
class MemoryType;
313
class TagType;
314
315
class WASM_API_EXTERN ExternType {
316
  friend class destroyer;
317
  void destroy();
318
319
protected:
320
  ExternType() = default;
321
  ~ExternType() = default;
322
323
public:
324
  auto copy() const-> own<ExternType>;
325
326
  auto kind() const -> ExternKind;
327
328
  auto func() -> FuncType*;
329
  auto global() -> GlobalType*;
330
  auto table() -> TableType*;
331
  auto memory() -> MemoryType*;
332
  auto tag() -> TagType*;
333
334
  auto func() const -> const FuncType*;
335
  auto global() const -> const GlobalType*;
336
  auto table() const -> const TableType*;
337
  auto memory() const -> const MemoryType*;
338
  auto tag() const -> const TagType*;
339
};
340
341
342
// Function Types
343
344
class WASM_API_EXTERN FuncType : public ExternType {
345
  friend class destroyer;
346
  void destroy();
347
348
protected:
349
  FuncType() = default;
350
  ~FuncType() = default;
351
352
public:
353
  static auto make(
354
    ownvec<ValType>&& params = ownvec<ValType>::make(),
355
    ownvec<ValType>&& results = ownvec<ValType>::make()
356
  ) -> own<FuncType>;
357
358
  auto copy() const -> own<FuncType>;
359
360
  auto params() const -> const ownvec<ValType>&;
361
  auto results() const -> const ownvec<ValType>&;
362
};
363
364
365
// Global Types
366
367
class WASM_API_EXTERN GlobalType : public ExternType {
368
  friend class destroyer;
369
  void destroy();
370
371
protected:
372
  GlobalType() = default;
373
  ~GlobalType() = default;
374
375
public:
376
  static auto make(own<ValType>&&, Mutability) -> own<GlobalType>;
377
  auto copy() const -> own<GlobalType>;
378
379
  auto content() const -> const ValType*;
380
  auto mutability() const -> Mutability;
381
};
382
383
384
// Table Types
385
386
class WASM_API_EXTERN TableType : public ExternType {
387
  friend class destroyer;
388
  void destroy();
389
390
protected:
391
  TableType() = default;
392
  ~TableType() = default;
393
394
public:
395
  static auto make(own<ValType>&&, Limits) -> own<TableType>;
396
  auto copy() const -> own<TableType>;
397
398
  auto element() const -> const ValType*;
399
  auto limits() const -> const Limits&;
400
};
401
402
403
// Memory Types
404
405
class WASM_API_EXTERN MemoryType : public ExternType {
406
  friend class destroyer;
407
  void destroy();
408
409
protected:
410
  MemoryType() = default;
411
  ~MemoryType() = default;
412
413
public:
414
  static auto make(Limits) -> own<MemoryType>;
415
  auto copy() const -> own<MemoryType>;
416
417
  auto limits() const -> const Limits&;
418
};
419
420
421
// Tag Types
422
423
class WASM_API_EXTERN TagType : public ExternType {
424
  friend class destroyer;
425
  void destroy();
426
427
protected:
428
  TagType() = default;
429
  ~TagType() = default;
430
431
public:
432
  static auto make(own<FuncType>&&) -> own<TagType>;
433
  auto copy() const -> own<TagType>;
434
435
  auto functype() const -> const FuncType*;
436
};
437
438
439
// Import Types
440
441
using Name = vec<byte_t>;
442
443
class WASM_API_EXTERN ImportType {
444
  friend class destroyer;
445
  void destroy();
446
447
protected:
448
  ImportType() = default;
449
  ~ImportType() = default;
450
451
public:
452
  static auto make(Name&& module, Name&& name, own<ExternType>&&) ->
453
    own<ImportType>;
454
  auto copy() const -> own<ImportType>;
455
456
  auto module() const -> const Name&;
457
  auto name() const -> const Name&;
458
  auto type() const -> const ExternType*;
459
};
460
461
462
// Export Types
463
464
class WASM_API_EXTERN ExportType {
465
  friend class destroyer;
466
  void destroy();
467
468
protected:
469
  ExportType() = default;
470
  ~ExportType() = default;
471
472
public:
473
  static auto make(Name&&, own<ExternType>&&) -> own<ExportType>;
474
  auto copy() const -> own<ExportType>;
475
476
  auto name() const -> const Name&;
477
  auto type() const -> const ExternType*;
478
};
479
480
481
///////////////////////////////////////////////////////////////////////////////
482
// Runtime Objects
483
484
// References
485
486
class WASM_API_EXTERN Ref {
487
  friend class destroyer;
488
  void destroy();
489
490
protected:
491
  Ref() = default;
492
  ~Ref() = default;
493
494
public:
495
  auto copy() const -> own<Ref>;
496
  auto same(const Ref*) const -> bool;
497
498
  auto get_host_info() const -> void*;
499
  void set_host_info(void* info, void (*finalizer)(void*) = nullptr);
500
};
501
502
503
// Values
504
505
class Val {
506
  ValKind kind_;
507
  union impl {
508
    int32_t i32;
509
    int64_t i64;
510
    float32_t f32;
511
    float64_t f64;
512
    Ref* ref;
513
  } impl_;
514
515
0
  Val(ValKind kind, impl impl) : kind_(kind), impl_(impl) {}
516
517
public:
518
0
  Val() : kind_(ValKind::EXTERNREF) { impl_.ref = nullptr; }
519
0
  explicit Val(int32_t i) : kind_(ValKind::I32) { impl_.i32 = i; }
520
0
  explicit Val(int64_t i) : kind_(ValKind::I64) { impl_.i64 = i; }
521
0
  explicit Val(float32_t z) : kind_(ValKind::F32) { impl_.f32 = z; }
522
0
  explicit Val(float64_t z) : kind_(ValKind::F64) { impl_.f64 = z; }
523
0
  explicit Val(own<Ref>&& r) : kind_(ValKind::EXTERNREF) { impl_.ref = r.release(); }
524
525
0
  Val(Val&& that) : kind_(that.kind_), impl_(that.impl_) {
526
0
    if (is_ref()) that.impl_.ref = nullptr;
527
0
  }
528
529
0
  ~Val() {
530
0
    reset();
531
0
  }
532
533
0
  auto is_num() const -> bool { return wasm::is_num(kind_); }
534
0
  auto is_ref() const -> bool { return wasm::is_ref(kind_); }
535
536
0
  static auto i32(int32_t x) -> Val { return Val(x); }
537
0
  static auto i64(int64_t x) -> Val { return Val(x); }
538
0
  static auto f32(float32_t x) -> Val { return Val(x); }
539
0
  static auto f64(float64_t x) -> Val { return Val(x); }
540
0
  static auto ref(own<Ref>&& x) -> Val { return Val(std::move(x)); }
541
  template<class T> inline static auto make(T x) -> Val;
542
  template<class T> inline static auto make(own<T>&& x) -> Val;
543
544
0
  void reset() {
545
0
    if (is_ref() && impl_.ref) {
546
0
      destroyer()(impl_.ref);
547
0
      impl_.ref = nullptr;
548
0
    }
549
0
  }
550
551
0
  void reset(Val& that) {
552
0
    reset();
553
0
    kind_ = that.kind_;
554
0
    impl_ = that.impl_;
555
0
    if (is_ref()) that.impl_.ref = nullptr;
556
0
  }
557
558
0
  auto operator=(Val&& that) -> Val& {
559
0
    reset(that);
560
0
    return *this;
561
0
  }
562
563
0
  auto kind() const -> ValKind { return kind_; }
564
0
  auto i32() const -> int32_t { assert(kind_ == ValKind::I32); return impl_.i32; }
565
0
  auto i64() const -> int64_t { assert(kind_ == ValKind::I64); return impl_.i64; }
566
0
  auto f32() const -> float32_t { assert(kind_ == ValKind::F32); return impl_.f32; }
567
0
  auto f64() const -> float64_t { assert(kind_ == ValKind::F64); return impl_.f64; }
568
0
  auto ref() const -> Ref* { assert(is_ref()); return impl_.ref; }
569
  template<class T> inline auto get() const -> T;
570
571
0
  auto release_ref() -> own<Ref> {
572
0
    assert(is_ref());
573
0
    auto ref = impl_.ref;
574
0
    impl_.ref = nullptr;
575
0
    return own<Ref>(ref);
576
0
  }
577
578
0
  auto copy() const -> Val {
579
0
    if (is_ref() && impl_.ref != nullptr) {
580
      // TODO(mvsc): MVSC cannot handle this:
581
      // impl impl = {.ref = impl_.ref->copy().release()};
582
0
      impl impl;
583
0
      impl.ref = impl_.ref->copy().release();
584
0
      return Val(kind_, impl);
585
0
    } else {
586
0
      return Val(kind_, impl_);
587
0
    }
588
0
  }
589
};
590
591
592
0
template<> inline auto Val::make<int32_t>(int32_t x) -> Val { return Val(x); }
593
0
template<> inline auto Val::make<int64_t>(int64_t x) -> Val { return Val(x); }
594
0
template<> inline auto Val::make<float32_t>(float32_t x) -> Val { return Val(x); }
595
0
template<> inline auto Val::make<float64_t>(float64_t x) -> Val { return Val(x); }
596
0
template<> inline auto Val::make<Ref>(own<Ref>&& x) -> Val {
597
0
  return Val(std::move(x));
598
0
}
599
600
0
template<> inline auto Val::make<uint32_t>(uint32_t x) -> Val {
601
0
  return Val(static_cast<int32_t>(x));
602
0
}
603
0
template<> inline auto Val::make<uint64_t>(uint64_t x) -> Val {
604
0
  return Val(static_cast<int64_t>(x));
605
0
}
606
607
0
template<> inline auto Val::get<int32_t>() const -> int32_t { return i32(); }
608
0
template<> inline auto Val::get<int64_t>() const -> int64_t { return i64(); }
609
0
template<> inline auto Val::get<float32_t>() const -> float32_t { return f32(); }
610
0
template<> inline auto Val::get<float64_t>() const -> float64_t { return f64(); }
611
0
template<> inline auto Val::get<Ref*>() const -> Ref* { return ref(); }
612
613
0
template<> inline auto Val::get<uint32_t>() const -> uint32_t {
614
0
  return static_cast<uint32_t>(i32());
615
0
}
616
0
template<> inline auto Val::get<uint64_t>() const -> uint64_t {
617
0
  return static_cast<uint64_t>(i64());
618
0
}
619
620
621
// Traps
622
623
using Message = vec<byte_t>;  // null terminated
624
625
class Instance;
626
627
class WASM_API_EXTERN Frame {
628
  friend class destroyer;
629
  void destroy();
630
631
protected:
632
  Frame() = default;
633
  ~Frame() = default;
634
635
public:
636
  auto copy() const -> own<Frame>;
637
638
  auto instance() const -> Instance*;
639
  auto func_index() const -> uint32_t;
640
  auto func_offset() const -> size_t;
641
  auto module_offset() const -> size_t;
642
};
643
644
class WASM_API_EXTERN Trap : public Ref {
645
  friend class destroyer;
646
  void destroy();
647
648
protected:
649
  Trap() = default;
650
  ~Trap() = default;
651
652
public:
653
  static auto make(Store*, const Message& msg) -> own<Trap>;
654
  auto copy() const -> own<Trap>;
655
656
  auto message() const -> Message;
657
  auto origin() const -> own<Frame>;  // may be null
658
  auto trace() const -> ownvec<Frame>;  // may be empty, origin first
659
};
660
661
662
// Modules
663
664
template<class T> class WASM_API_EXTERN Shared;
665
666
class WASM_API_EXTERN Module : public Ref {
667
  friend class destroyer;
668
  void destroy();
669
670
protected:
671
  Module() = default;
672
  ~Module() = default;
673
674
public:
675
  static auto validate(Store*, const vec<byte_t>& binary) -> bool;
676
  static auto make(Store*, const vec<byte_t>& binary) -> own<Module>;
677
  auto copy() const -> own<Module>;
678
679
  auto imports() const -> ownvec<ImportType>;
680
  auto exports() const -> ownvec<ExportType>;
681
682
  auto share() const -> own<Shared<Module>>;
683
  static auto obtain(Store*, const Shared<Module>*) -> own<Module>;
684
685
  auto serialize() const -> vec<byte_t>;
686
  static auto deserialize(Store*, const vec<byte_t>&) -> own<Module>;
687
};
688
689
690
// Shared objects
691
692
template<>
693
class WASM_API_EXTERN Shared<Module> {
694
  friend class destroyer;
695
  void destroy();
696
697
protected:
698
  Shared() = default;
699
  ~Shared() = default;
700
};
701
702
703
// Foreign Objects
704
705
class WASM_API_EXTERN Foreign : public Ref {
706
  friend class destroyer;
707
  void destroy();
708
709
protected:
710
  Foreign() = default;
711
  ~Foreign() = default;
712
713
public:
714
  static auto make(Store*) -> own<Foreign>;
715
  auto copy() const -> own<Foreign>;
716
};
717
718
719
// Externals
720
721
class Func;
722
class Global;
723
class Table;
724
class Memory;
725
726
class WASM_API_EXTERN Extern : public Ref {
727
  friend class destroyer;
728
  void destroy();
729
730
protected:
731
  Extern() = default;
732
  ~Extern() = default;
733
734
public:
735
  auto copy() const -> own<Extern>;
736
737
  auto kind() const -> ExternKind;
738
  auto type() const -> own<ExternType>;
739
740
  auto func() -> Func*;
741
  auto global() -> Global*;
742
  auto table() -> Table*;
743
  auto memory() -> Memory*;
744
745
  auto func() const -> const Func*;
746
  auto global() const -> const Global*;
747
  auto table() const -> const Table*;
748
  auto memory() const -> const Memory*;
749
};
750
751
752
// Function Instances
753
754
class WASM_API_EXTERN Func : public Extern {
755
  friend class destroyer;
756
  void destroy();
757
758
protected:
759
  Func() = default;
760
  ~Func() = default;
761
762
public:
763
  using callback = auto (*)(const vec<Val>&, vec<Val>&) -> own<Trap>;
764
  using callback_with_env = auto (*)(void*, const vec<Val>&, vec<Val>&) -> own<Trap>;
765
766
  static auto make(Store*, const FuncType*, callback) -> own<Func>;
767
  static auto make(Store*, const FuncType*, callback_with_env,
768
    void*, void (*finalizer)(void*) = nullptr) -> own<Func>;
769
  auto copy() const -> own<Func>;
770
771
  auto type() const -> own<FuncType>;
772
  auto param_arity() const -> size_t;
773
  auto result_arity() const -> size_t;
774
775
  auto call(const vec<Val>&, vec<Val>&) const -> own<Trap>;
776
};
777
778
779
// Global Instances
780
781
class WASM_API_EXTERN Global : public Extern {
782
  friend class destroyer;
783
  void destroy();
784
785
protected:
786
  Global() = default;
787
  ~Global() = default;
788
789
 public:
790
  static auto make(Store*, const GlobalType*, const Val&) -> own<Global>;
791
  auto copy() const -> own<Global>;
792
793
  auto type() const -> own<GlobalType>;
794
  auto get() const -> Val;
795
  void set(const Val&);
796
};
797
798
799
// Table Instances
800
801
class WASM_API_EXTERN Table : public Extern {
802
  friend class destroyer;
803
  void destroy();
804
805
protected:
806
  Table() = default;
807
  ~Table() = default;
808
809
public:
810
  using size_t = uint32_t;
811
812
  static auto make(
813
    Store*, const TableType*, const Ref* init = nullptr) -> own<Table>;
814
  auto copy() const -> own<Table>;
815
816
  auto type() const -> own<TableType>;
817
  auto get(size_t index) const -> own<Ref>;
818
  auto set(size_t index, const Ref*) -> bool;
819
  auto size() const -> size_t;
820
  auto grow(size_t delta, const Ref* init = nullptr) -> bool;
821
};
822
823
824
// Memory Instances
825
826
class WASM_API_EXTERN Memory : public Extern {
827
  friend class destroyer;
828
  void destroy();
829
830
protected:
831
  Memory() = default;
832
  ~Memory() = default;
833
834
public:
835
  static auto make(Store*, const MemoryType*) -> own<Memory>;
836
  auto copy() const -> own<Memory>;
837
838
  using pages_t = uint32_t;
839
840
  static const size_t page_size = 0x10000;
841
842
  auto type() const -> own<MemoryType>;
843
  auto data() const -> byte_t*;
844
  auto data_size() const -> size_t;
845
  auto size() const -> pages_t;
846
  auto grow(pages_t delta) -> bool;
847
};
848
849
850
// Module Instances
851
852
class WASM_API_EXTERN Instance : public Ref {
853
  friend class destroyer;
854
  void destroy();
855
856
protected:
857
  Instance() = default;
858
  ~Instance() = default;
859
860
public:
861
  static auto make(
862
    Store*, const Module*, const vec<Extern*>&, own<Trap>* = nullptr
863
  ) -> own<Instance>;
864
  auto copy() const -> own<Instance>;
865
866
  auto exports() const -> ownvec<Extern>;
867
};
868
869
870
///////////////////////////////////////////////////////////////////////////////
871
872
}  // namespace wasm
873
874
#endif  // #ifdef WASM_HH