Coverage Report

Created: 2026-09-28 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/api/wasm_c.cpp
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
#include <algorithm>
5
#include <unordered_map>
6
7
#include "common/configure.h"
8
#include "common/errcode.h"
9
#include "common/span.h"
10
11
#include "ast/module.h"
12
#include "executor/executor.h"
13
#include "loader/loader.h"
14
#include "runtime/storemgr.h"
15
#include "validator/validator.h"
16
17
// When building the library on Windows, align WASM_API_EXTERN with
18
// WASMEDGE_CAPI_EXPORT so that declarations and definitions have
19
// the same linkage attribute.
20
#if defined(_WIN32) && !defined(__MINGW32__) &&                                \
21
    defined(WASMEDGE_COMPILE_LIBRARY)
22
#define WASM_API_EXTERN __declspec(dllexport)
23
#endif
24
25
// Suppress deprecated-copy-with-dtor warnings from thirdparty headers
26
// triggered by dllexport forcing instantiation of implicit operators.
27
#if defined(__clang__)
28
#pragma clang diagnostic push
29
#pragma clang diagnostic ignored "-Wdeprecated-copy-with-dtor"
30
#endif
31
32
#include "wasm.h"
33
#include "wasm.hh"
34
35
#if defined(__clang__)
36
#pragma clang diagnostic pop
37
#endif
38
39
#include "wasmedge/wasmedge.h"
40
41
#ifndef OWN
42
#define OWN
43
#endif
44
45
namespace {
46
47
// WasmEdge::ValType to wasm::ValKind conversion.
48
0
wasm::ValKind conv_valtype_from_wasmedge(const WasmEdge::ValType &vt) {
49
0
  if (vt.isNumType()) {
50
0
    switch (vt.getCode()) {
51
0
    case WasmEdge::TypeCode::I32:
52
0
      return wasm::ValKind::I32;
53
0
    case WasmEdge::TypeCode::I64:
54
0
      return wasm::ValKind::I64;
55
0
    case WasmEdge::TypeCode::F32:
56
0
      return wasm::ValKind::F32;
57
0
    case WasmEdge::TypeCode::F64:
58
0
      return wasm::ValKind::F64;
59
0
    default:
60
0
      break;
61
0
    }
62
0
  } else if (vt.isFuncRefType()) {
63
0
    return wasm::ValKind::FUNCREF;
64
0
  } else if (vt.isExternRefType()) {
65
0
    return wasm::ValKind::EXTERNREF;
66
0
  }
67
  // v128 and other types are not supported in wasm C API yet.
68
0
  assumingUnreachable();
69
0
}
70
71
// WasmEdge::ValType (ref type) to wasm::ValKind conversion.
72
0
wasm::ValKind conv_reftype_from_wasmedge(const WasmEdge::ValType &vt) {
73
0
  if (vt.isFuncRefType()) {
74
0
    return wasm::ValKind::FUNCREF;
75
0
  } else if (vt.isExternRefType()) {
76
0
    return wasm::ValKind::EXTERNREF;
77
0
  } else {
78
0
    assumingUnreachable();
79
0
  }
80
0
}
81
82
// WasmEdge::ValMut to wasm::Mutability conversion.
83
0
wasm::Mutability conv_valmut_from_wasmedge(WasmEdge::ValMut mut) {
84
0
  switch (mut) {
85
0
  case WasmEdge::ValMut::Const:
86
0
    return wasm::Mutability::CONST;
87
0
  case WasmEdge::ValMut::Var:
88
0
    return wasm::Mutability::VAR;
89
0
  default:
90
0
    assumingUnreachable();
91
0
  }
92
0
}
93
94
// wasm::ValType to WasmEdge::ValType conversion.
95
0
WasmEdge::ValType conv_valtype_to_wasmedge(wasm::ValKind vt) {
96
0
  switch (vt) {
97
0
  case wasm::ValKind::I32:
98
0
    return WasmEdge::ValType(WasmEdge::TypeCode::I32);
99
0
  case wasm::ValKind::I64:
100
0
    return WasmEdge::ValType(WasmEdge::TypeCode::I64);
101
0
  case wasm::ValKind::F32:
102
0
    return WasmEdge::ValType(WasmEdge::TypeCode::F32);
103
0
  case wasm::ValKind::F64:
104
0
    return WasmEdge::ValType(WasmEdge::TypeCode::F64);
105
0
  case wasm::ValKind::FUNCREF:
106
0
    return WasmEdge::ValType(WasmEdge::TypeCode::FuncRef);
107
0
  case wasm::ValKind::EXTERNREF:
108
0
    return WasmEdge::ValType(WasmEdge::TypeCode::ExternRef);
109
0
  default:
110
0
    assumingUnreachable();
111
0
  }
112
0
}
113
114
// wasm::ValKind to WasmEdge::ValType (ref type) conversion.
115
0
WasmEdge::ValType conv_reftype_to_wasmedge(wasm::ValKind vt) {
116
0
  switch (vt) {
117
0
  case wasm::ValKind::FUNCREF:
118
0
    return WasmEdge::ValType(WasmEdge::TypeCode::FuncRef);
119
0
  case wasm::ValKind::EXTERNREF:
120
0
    return WasmEdge::ValType(WasmEdge::TypeCode::ExternRef);
121
0
  default:
122
0
    assumingUnreachable();
123
0
  }
124
0
}
125
126
// wasm::Mutability to WasmEdge::ValMut conversion.
127
0
WasmEdge::ValMut conv_valmut_to_wasmedge(wasm::Mutability mut) {
128
0
  switch (mut) {
129
0
  case wasm::Mutability::CONST:
130
0
    return WasmEdge::ValMut::Const;
131
0
  case wasm::Mutability::VAR:
132
0
    return WasmEdge::ValMut::Var;
133
0
  default:
134
0
    assumingUnreachable();
135
0
  }
136
0
}
137
138
// Make wasm::Limits from WasmEdge::AST::Limit.
139
0
wasm::Limits make_limits_from_wasmedge(const WasmEdge::AST::Limit &lm) {
140
0
  if (lm.hasMax()) {
141
0
    return wasm::Limits(static_cast<uint32_t>(lm.getMin()),
142
0
                        static_cast<uint32_t>(lm.getMax()));
143
0
  } else {
144
0
    return wasm::Limits(static_cast<uint32_t>(lm.getMin()));
145
0
  }
146
0
}
147
148
// Make wasm::own<wasm::FuncType> from WasmEdge::AST::FunctionType.
149
wasm::own<wasm::FuncType>
150
0
make_functype_from_wasmedge(const WasmEdge::AST::FunctionType &ft) {
151
0
  auto p = wasm::ownvec<wasm::ValType>::make_uninitialized(
152
0
      ft.getParamTypes().size());
153
0
  for (size_t i = 0; i < p.size(); ++i) {
154
0
    p[i] =
155
0
        wasm::ValType::make(conv_valtype_from_wasmedge(ft.getParamTypes()[i]));
156
0
  }
157
0
  auto r = wasm::ownvec<wasm::ValType>::make_uninitialized(
158
0
      ft.getReturnTypes().size());
159
0
  for (size_t i = 0; i < r.size(); ++i) {
160
0
    r[i] =
161
0
        wasm::ValType::make(conv_valtype_from_wasmedge(ft.getReturnTypes()[i]));
162
0
  }
163
0
  return wasm::FuncType::make(std::move(p), std::move(r));
164
0
}
165
166
// Make WasmEdge::AST::FunctionType from wasm::FuncType.
167
0
WasmEdge::AST::FunctionType make_functype_from_wasm(const wasm::FuncType &ft) {
168
0
  std::vector<WasmEdge::ValType> p(ft.params().size()), r(ft.results().size());
169
0
  for (size_t i = 0; i < p.size(); ++i) {
170
0
    p[i] = conv_valtype_to_wasmedge(ft.params()[i]->kind());
171
0
  }
172
0
  for (size_t i = 0; i < r.size(); ++i) {
173
0
    r[i] = conv_valtype_to_wasmedge(ft.results()[i]->kind());
174
0
  }
175
0
  return WasmEdge::AST::FunctionType(p, r);
176
0
}
177
178
// Make wasm::own<wasm::GlobalType> from WasmEdge::AST::GlobalType.
179
wasm::own<wasm::GlobalType>
180
0
make_globaltype_from_wasmedge(const WasmEdge::AST::GlobalType &gt) {
181
0
  return wasm::GlobalType::make(
182
0
      wasm::ValType::make(conv_valtype_from_wasmedge(gt.getValType())),
183
0
      conv_valmut_from_wasmedge(gt.getValMut()));
184
0
}
185
186
// Make wasm::own<wasm::TableType> from WasmEdge::AST::TableType.
187
wasm::own<wasm::TableType>
188
0
make_tabletype_from_wasmedge(const WasmEdge::AST::TableType &tt) {
189
0
  return wasm::TableType::make(
190
0
      wasm::ValType::make(conv_reftype_from_wasmedge(tt.getRefType())),
191
0
      make_limits_from_wasmedge(tt.getLimit()));
192
0
}
193
194
// Make wasm::own<wasm::MemoryType> from WasmEdge::AST::MemoryType.
195
wasm::own<wasm::MemoryType>
196
0
make_memorytype_from_wasmedge(const WasmEdge::AST::MemoryType &mt) {
197
0
  return wasm::MemoryType::make(make_limits_from_wasmedge(mt.getLimit()));
198
0
}
199
200
// Make wasm::own<wasm::TagType> from WasmEdge's tag-defining SubType.
201
wasm::own<wasm::TagType>
202
0
make_tagtype_from_wasmedge(const WasmEdge::AST::SubType &st) {
203
0
  if (st.getCompositeType().isFunc()) {
204
0
    return wasm::TagType::make(
205
0
        make_functype_from_wasmedge(st.getCompositeType().getFuncType()));
206
0
  }
207
0
  return wasm::TagType::make(wasm::FuncType::make());
208
0
}
209
210
// wasm_allocmgr_t: the allocation manager for the runtime objects.
211
struct wasm_allocmgr_t {
212
  // Entry for each tracked runtime object, storing refcount, destroyer,
213
  // and cached host info for type-safe cleanup in the destructor.
214
  struct ref_entry_t {
215
    size_t refcount;
216
    std::function<void(void *)> destroyer;
217
    void *info;
218
    void (*finalizer)(void *);
219
  };
220
221
  template <typename T>
222
  void link(
223
0
      T *target, void (*dest)(void *) = [](void *target) {
224
0
        delete static_cast<T *>(target);
225
0
      }) {
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_trap_t>(wasm_trap_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_module_t>(wasm_module_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_func_t>(wasm_func_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_foreign_t>(wasm_foreign_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_global_t>(wasm_global_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_table_t>(wasm_table_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_memory_t>(wasm_memory_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_instance_t>(wasm_instance_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_ref_t>(wasm_ref_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
Unexecuted instantiation: wasm_c.cpp:(anonymous namespace)::wasm_allocmgr_t::link<wasm_extern_t>(wasm_extern_t*, void (*)(void*))::{default arg#1}::{lambda(void*)#1}::operator()(void*) const
226
0
    auto it = entries.find(static_cast<void *>(target));
227
0
    if (it == entries.end()) {
228
0
      entries.emplace(static_cast<void *>(target),
229
0
                      ref_entry_t{1, dest, target->info, target->finalizer});
230
0
    } else {
231
0
      it->second.refcount += 1;
232
0
    }
233
0
  }
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_trap_t>(wasm_trap_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_module_t>(wasm_module_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_func_t>(wasm_func_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_foreign_t>(wasm_foreign_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_global_t>(wasm_global_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_table_t>(wasm_table_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_memory_t>(wasm_memory_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_instance_t>(wasm_instance_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_ref_t>(wasm_ref_t*, void (*)(void*))
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::link<wasm_extern_t>(wasm_extern_t*, void (*)(void*))
234
235
0
  template <typename T> void unlink(T *target) {
236
0
    auto it = entries.find(static_cast<void *>(target));
237
0
    if (it != entries.end()) {
238
0
      it->second.refcount -= 1;
239
0
      if (it->second.refcount == 0) {
240
0
        if (target->finalizer) {
241
0
          target->finalizer(target->info);
242
0
        }
243
        // Erase the entry before calling the destroyer to prevent
244
        // re-entrance if the destructor chain calls unlink() again.
245
0
        auto dest = std::move(it->second.destroyer);
246
0
        entries.erase(it);
247
0
        dest(target);
248
0
      }
249
0
    }
250
0
  }
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_ref_t>(wasm_ref_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_trap_t>(wasm_trap_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_foreign_t>(wasm_foreign_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_module_t>(wasm_module_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_func_t>(wasm_func_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_global_t>(wasm_global_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_table_t>(wasm_table_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_memory_t>(wasm_memory_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_extern_t>(wasm_extern_t*)
Unexecuted instantiation: wasm_c.cpp:void (anonymous namespace)::wasm_allocmgr_t::unlink<wasm_instance_t>(wasm_instance_t*)
251
252
  ~wasm_allocmgr_t();
253
254
private:
255
  std::unordered_map<void *, ref_entry_t> entries;
256
  std::unordered_map<const WasmEdge::Runtime::Instance::FunctionInstance *,
257
                     void *>
258
      funcmap;
259
};
260
261
// Value conversion forward declaration.
262
inline wasm_val_t conv_cval_from_wasmedge(const WasmEdge::ValVariant &,
263
                                          const WasmEdge::ValType &);
264
inline wasm::Val conv_cppval_from_wasmedge(const WasmEdge::ValVariant &,
265
                                           const WasmEdge::ValType &);
266
inline WasmEdge::ValVariant conv_cval_to_wasmedge(const wasm_val_t &);
267
inline WasmEdge::ValVariant conv_cppval_to_wasmedge(const wasm::Val &);
268
inline wasm::Val conv_val_to_cpp(const wasm_val_t &);
269
inline wasm_val_t conv_val_to_c(const wasm::Val &);
270
271
// wasm_hostfunc_t: the wrapper to host function in wasm C/C++ API.
272
class wasm_hostfunc_t : public WasmEdge::Runtime::HostFunctionBase {
273
public:
274
  wasm_hostfunc_t(const wasm::FuncType &ft, wasm_func_callback_t cb) noexcept
275
0
      : WasmEdge::Runtime::HostFunctionBase(0), type(api_type_enum::C),
276
0
        env(nullptr), finalizer(nullptr) {
277
0
    callback.c = cb;
278
0
    DefType = WasmEdge::AST::SubType(make_functype_from_wasm(ft));
279
0
  }
280
  wasm_hostfunc_t(const wasm::FuncType &ft, wasm_func_callback_with_env_t cb,
281
                  void *e, void (*fin)(void *)) noexcept
282
0
      : WasmEdge::Runtime::HostFunctionBase(0), type(api_type_enum::C_ENV),
283
0
        env(e), finalizer(fin) {
284
0
    callback.c_env = cb;
285
0
    DefType = WasmEdge::AST::SubType(make_functype_from_wasm(ft));
286
0
  }
287
  wasm_hostfunc_t(const wasm::FuncType &ft, wasm::Func::callback cb) noexcept
288
0
      : WasmEdge::Runtime::HostFunctionBase(0), type(api_type_enum::CPP),
289
0
        env(nullptr), finalizer(nullptr) {
290
0
    callback.cpp = cb;
291
0
    DefType = WasmEdge::AST::SubType(make_functype_from_wasm(ft));
292
0
  }
293
  wasm_hostfunc_t(const wasm::FuncType &ft, wasm::Func::callback_with_env cb,
294
                  void *e, void (*fin)(void *)) noexcept
295
0
      : WasmEdge::Runtime::HostFunctionBase(0), type(api_type_enum::CPP_ENV),
296
0
        env(e), finalizer(fin) {
297
0
    callback.cpp_env = cb;
298
0
    DefType = WasmEdge::AST::SubType(make_functype_from_wasm(ft));
299
0
  }
300
  // Alias copy: share callback + env without the finalizer, used when
301
  // importing a host wasm_func_t into another instance.
302
  explicit wasm_hostfunc_t(const wasm_hostfunc_t &other) noexcept
303
0
      : WasmEdge::Runtime::HostFunctionBase(0), type(other.type),
304
0
        callback(other.callback), env(other.env), finalizer(nullptr) {
305
0
    DefType = other.DefType;
306
0
  }
307
0
  ~wasm_hostfunc_t() noexcept override {
308
0
    if (finalizer) {
309
0
      finalizer(env);
310
0
    }
311
0
  }
312
313
  WasmEdge::Expect<void>
314
  run(const WasmEdge::Runtime::CallingFrame &,
315
      WasmEdge::Span<const WasmEdge::ValVariant> Args,
316
0
      WasmEdge::Span<WasmEdge::ValVariant> Rets) override {
317
0
    auto &ptypes = getFuncType().getParamTypes();
318
0
    auto &rtypes = getFuncType().getReturnTypes();
319
320
0
    if (type == api_type_enum::C || type == api_type_enum::C_ENV) {
321
      // Prepare the arguments.
322
0
      std::vector<wasm_val_t> pdata(ptypes.size());
323
0
      std::vector<wasm_val_t> rdata(rtypes.size());
324
0
      wasm_val_vec_t params = {ptypes.size(), pdata.data()};
325
0
      wasm_val_vec_t returns = {rtypes.size(), rdata.data()};
326
0
      for (size_t i = 0; i < Args.size(); ++i) {
327
0
        params.data[i] = conv_cval_from_wasmedge(Args[i], ptypes[i]);
328
0
      }
329
330
      // Invocation.
331
0
      wasm_trap_t *trap = nullptr;
332
0
      if (callback.c) {
333
0
        if (type == api_type_enum::C) {
334
0
          trap = callback.c(&params, &returns);
335
0
        } else {
336
0
          trap = callback.c_env(env, &params, &returns);
337
0
        }
338
0
      }
339
340
      // Get the results.
341
0
      if (trap) {
342
0
        wasm_trap_delete(trap);
343
0
        return Unexpect(WasmEdge::ErrCode::Value::HostFuncError);
344
0
      }
345
0
      for (size_t i = 0; i < Rets.size(); ++i) {
346
0
        Rets[i] = conv_cval_to_wasmedge(returns.data[i]);
347
0
      }
348
0
    } else {
349
      // Prepare the arguments.
350
0
      auto params = wasm::vec<wasm::Val>::make_uninitialized(ptypes.size());
351
0
      auto returns = wasm::vec<wasm::Val>::make_uninitialized(rtypes.size());
352
0
      for (size_t i = 0; i < Args.size(); ++i) {
353
0
        params[i] = conv_cppval_from_wasmedge(Args[i], ptypes[i]);
354
0
      }
355
356
      // Invocation.
357
0
      wasm::own<wasm::Trap> trap;
358
0
      if (callback.cpp) {
359
0
        if (type == api_type_enum::CPP) {
360
0
          trap = callback.cpp(params, returns);
361
0
        } else {
362
0
          trap = callback.cpp_env(env, params, returns);
363
0
        }
364
0
      }
365
366
      // Get the results.
367
0
      if (trap) {
368
0
        return Unexpect(WasmEdge::ErrCode::Value::HostFuncError);
369
0
      }
370
0
      for (size_t i = 0; i < Rets.size(); ++i) {
371
0
        Rets[i] = conv_cppval_to_wasmedge(returns[i]);
372
0
      }
373
0
    }
374
0
    return {};
375
0
  }
376
377
private:
378
  enum class api_type_enum { C, CPP, C_ENV, CPP_ENV };
379
  api_type_enum type;
380
  union {
381
    wasm_func_callback_t c;
382
    wasm::Func::callback cpp;
383
    wasm_func_callback_with_env_t c_env;
384
    wasm::Func::callback_with_env cpp_env;
385
  } callback;
386
  void *env;
387
  void (*finalizer)(void *);
388
};
389
390
// wasm_category_val implementation.
391
template <class C> struct wasm_externkind_val;
392
template <> struct wasm_externkind_val<wasm::FuncType> {
393
  static const auto value = wasm::ExternKind::FUNC;
394
};
395
template <> struct wasm_externkind_val<wasm::GlobalType> {
396
  static const auto value = wasm::ExternKind::GLOBAL;
397
};
398
template <> struct wasm_externkind_val<wasm::TableType> {
399
  static const auto value = wasm::ExternKind::TABLE;
400
};
401
template <> struct wasm_externkind_val<wasm::MemoryType> {
402
  static const auto value = wasm::ExternKind::MEMORY;
403
};
404
template <> struct wasm_externkind_val<wasm::TagType> {
405
  static const auto value = wasm::ExternKind::TAG;
406
};
407
408
// wasm_category_enum for the runtime objects.
409
enum class wasm_category_enum : uint8_t {
410
  TRAP,
411
  FOREIGN,
412
  MODULE,
413
  FUNC,
414
  GLOBAL,
415
  TABLE,
416
  MEMORY,
417
  INSTANCE
418
};
419
420
// wasm_category_val implementation.
421
template <class C> struct wasm_category_val;
422
template <> struct wasm_category_val<wasm_trap_t> {
423
  static const auto value = wasm_category_enum::TRAP;
424
};
425
template <> struct wasm_category_val<wasm_foreign_t> {
426
  static const auto value = wasm_category_enum::FOREIGN;
427
};
428
template <> struct wasm_category_val<wasm_module_t> {
429
  static const auto value = wasm_category_enum::MODULE;
430
};
431
template <> struct wasm_category_val<wasm_func_t> {
432
  static const auto value = wasm_category_enum::FUNC;
433
};
434
template <> struct wasm_category_val<wasm_global_t> {
435
  static const auto value = wasm_category_enum::GLOBAL;
436
};
437
template <> struct wasm_category_val<wasm_table_t> {
438
  static const auto value = wasm_category_enum::TABLE;
439
};
440
template <> struct wasm_category_val<wasm_memory_t> {
441
  static const auto value = wasm_category_enum::MEMORY;
442
};
443
template <> struct wasm_category_val<wasm_instance_t> {
444
  static const auto value = wasm_category_enum::INSTANCE;
445
};
446
447
// Imports shim that aliases (does not own) the user's runtime instances.
448
class wasm_import_module_t
449
    : public WasmEdge::Runtime::Instance::ModuleInstance {
450
public:
451
  explicit wasm_import_module_t(std::string_view name) noexcept
452
0
      : WasmEdge::Runtime::Instance::ModuleInstance(name) {}
453
454
  void aliasFunc(std::string_view name,
455
0
                 WasmEdge::Runtime::Instance::FunctionInstance *fi) {
456
    // Native/compiled funcs: linker reads the type from fi->getModule().
457
    // Host funcs have no owner module, so register a copy under this shim.
458
0
    if (fi->getModule()) {
459
0
      importFunction(fi);
460
0
      exportFunction(name, FuncCount++);
461
0
    } else {
462
0
      const auto &orig = static_cast<wasm_hostfunc_t &>(fi->getHostFunc());
463
0
      addHostFunc(name, std::make_unique<wasm_hostfunc_t>(orig));
464
0
    }
465
0
  }
466
  void aliasGlobal(std::string_view name,
467
0
                   WasmEdge::Runtime::Instance::GlobalInstance *gi) {
468
0
    importGlobal(gi);
469
0
    exportGlobal(name, GlobCount++);
470
0
  }
471
  void aliasTable(std::string_view name,
472
0
                  WasmEdge::Runtime::Instance::TableInstance *ti) {
473
0
    importTable(ti);
474
0
    exportTable(name, TabCount++);
475
0
  }
476
  void aliasMemory(std::string_view name,
477
0
                   WasmEdge::Runtime::Instance::MemoryInstance *mi) {
478
0
    importMemory(mi);
479
0
    exportMemory(name, MemCount++);
480
0
  }
481
482
private:
483
  uint32_t FuncCount = 0;
484
  uint32_t GlobCount = 0;
485
  uint32_t TabCount = 0;
486
  uint32_t MemCount = 0;
487
};
488
489
} // namespace
490
491
// wasm_config_t implementation.
492
struct wasm_config_t : public wasm::Config {
493
0
  wasm_config_t() noexcept = default;
494
  WasmEdge::Configure conf;
495
};
496
497
// wasm_engine_t implementation.
498
struct wasm_engine_t : public wasm::Engine {
499
  wasm_engine_t() noexcept
500
0
      : mconf(new (std::nothrow) wasm_config_t),
501
0
        exec(static_cast<wasm_config_t *>(mconf.get())->conf, nullptr) {}
502
  wasm_engine_t(wasm::own<wasm::Config> &&c) noexcept
503
0
      : mconf(std::move(c)),
504
0
        exec(static_cast<wasm_config_t *>(mconf.get())->conf, nullptr) {}
505
  wasm::own<wasm::Config> mconf;
506
  WasmEdge::Executor::Executor exec;
507
};
508
509
// wasm_store_t implementation.
510
struct wasm_store_t : public wasm::Store {
511
  wasm_store_t(wasm::Engine *e) noexcept
512
0
      : engine(static_cast<wasm_engine_t *>(e)),
513
0
        load(static_cast<wasm_config_t *>(engine->mconf.get())->conf),
514
0
        valid(static_cast<wasm_config_t *>(engine->mconf.get())->conf),
515
0
        store() {}
516
  wasm_engine_t *engine;
517
  wasm_allocmgr_t allocmgr;
518
  WasmEdge::Loader::Loader load;
519
  WasmEdge::Validator::Validator valid;
520
  WasmEdge::Runtime::StoreManager store;
521
};
522
523
// wasm_valtype_t implementation.
524
struct wasm_valtype_t : public wasm::ValType {
525
36
  wasm_valtype_t(wasm::ValKind k) noexcept : mkind(k) {}
526
  wasm::ValKind mkind;
527
};
528
529
// wasm_externtype_base_t implementation.
530
template <class C> struct wasm_externtype_base_t : public C {
531
0
  wasm_externtype_base_t() noexcept : mkind(wasm_externkind_val<C>::value) {}
Unexecuted instantiation: wasm_externtype_base_t<wasm::FuncType>::wasm_externtype_base_t()
Unexecuted instantiation: wasm_externtype_base_t<wasm::GlobalType>::wasm_externtype_base_t()
Unexecuted instantiation: wasm_externtype_base_t<wasm::TableType>::wasm_externtype_base_t()
Unexecuted instantiation: wasm_externtype_base_t<wasm::MemoryType>::wasm_externtype_base_t()
Unexecuted instantiation: wasm_externtype_base_t<wasm::TagType>::wasm_externtype_base_t()
532
  wasm::ExternKind mkind;
533
};
534
535
// wasm_externtype_t implementation.
536
struct wasm_externtype_t : wasm_externtype_base_t<wasm::ExternType> {
537
  wasm_externtype_t() = delete;
538
};
539
540
// wasm_functype_t implementation.
541
struct wasm_functype_t : public wasm_externtype_base_t<wasm::FuncType> {
542
  wasm_functype_t(wasm::ownvec<wasm::ValType> &&vp,
543
                  wasm::ownvec<wasm::ValType> &&vr) noexcept
544
0
      : mparams(std::move(vp)), mresults(std::move(vr)) {}
545
  wasm::ownvec<wasm::ValType> mparams, mresults;
546
};
547
548
// wasm_globaltype_t implementation.
549
struct wasm_globaltype_t : public wasm_externtype_base_t<wasm::GlobalType> {
550
  wasm_globaltype_t(wasm::own<wasm::ValType> &&vt,
551
                    wasm::Mutability mut) noexcept
552
0
      : mcontent(std::move(vt)), mmutability(mut) {}
553
  wasm::own<wasm::ValType> mcontent;
554
  wasm::Mutability mmutability;
555
};
556
557
// wasm_tabletype_t implementation.
558
struct wasm_tabletype_t : public wasm_externtype_base_t<wasm::TableType> {
559
  wasm_tabletype_t(wasm::own<wasm::ValType> &&vt, wasm::Limits lim) noexcept
560
0
      : mvaltype(std::move(vt)), mlimits(lim) {}
561
  wasm::own<wasm::ValType> mvaltype;
562
  wasm::Limits mlimits;
563
};
564
565
// wasm_memorytype_t implementation.
566
struct wasm_memorytype_t : public wasm_externtype_base_t<wasm::MemoryType> {
567
0
  wasm_memorytype_t(wasm::Limits lim) noexcept : mlimits(lim) {}
568
  ~wasm_memorytype_t() noexcept = default;
569
  wasm::Limits mlimits;
570
};
571
572
// wasm_tagtype_t implementation.
573
struct wasm_tagtype_t : public wasm_externtype_base_t<wasm::TagType> {
574
  wasm_tagtype_t(wasm::own<wasm::FuncType> &&ft) noexcept
575
0
      : mfunctype(std::move(ft)) {}
576
  wasm::own<wasm::FuncType> mfunctype;
577
};
578
579
// wasm_importtype_t implementation.
580
struct wasm_importtype_t : public wasm::ImportType {
581
  wasm_importtype_t(wasm::Name &&mod, wasm::Name &&n,
582
                    wasm::own<wasm::ExternType> &&ext) noexcept
583
0
      : mmodname(std::move(mod)), mname(std::move(n)), mtype(std::move(ext)) {}
584
  wasm::Name mmodname, mname;
585
  wasm::own<wasm::ExternType> mtype;
586
};
587
588
// wasm_exporttype_t implementation.
589
struct wasm_exporttype_t : public wasm::ExportType {
590
  wasm_exporttype_t(wasm::Name &&n, wasm::own<wasm::ExternType> &&ext) noexcept
591
0
      : mname(std::move(n)), mtype(std::move(ext)) {}
592
  wasm::Name mname;
593
  wasm::own<wasm::ExternType> mtype;
594
};
595
596
// wasm_ref_base_t implementation.
597
template <class C> struct wasm_ref_base_t {
598
  // `inner` must hold the outer C* address (allocmgr's destroyer calls
599
  // delete on it); when wasm_ref_base_t is a non-first base, `this` differs.
600
  wasm_ref_base_t(wasm::Store *s) noexcept
601
0
      : store(static_cast<wasm_store_t *>(s)),
602
0
        category(wasm_category_val<C>::value), inner(static_cast<C *>(this)),
603
0
        info(nullptr), finalizer(nullptr) {
604
0
    increase_ref();
605
0
  }
Unexecuted instantiation: wasm_ref_base_t<wasm_trap_t>::wasm_ref_base_t(wasm::Store*)
Unexecuted instantiation: wasm_ref_base_t<wasm_module_t>::wasm_ref_base_t(wasm::Store*)
Unexecuted instantiation: wasm_ref_base_t<wasm_func_t>::wasm_ref_base_t(wasm::Store*)
Unexecuted instantiation: wasm_ref_base_t<wasm_foreign_t>::wasm_ref_base_t(wasm::Store*)
Unexecuted instantiation: wasm_ref_base_t<wasm_global_t>::wasm_ref_base_t(wasm::Store*)
Unexecuted instantiation: wasm_ref_base_t<wasm_table_t>::wasm_ref_base_t(wasm::Store*)
Unexecuted instantiation: wasm_ref_base_t<wasm_memory_t>::wasm_ref_base_t(wasm::Store*)
Unexecuted instantiation: wasm_ref_base_t<wasm_instance_t>::wasm_ref_base_t(wasm::Store*)
606
  wasm_ref_base_t(wasm::Store *s, const wasm_ref_base_t &ref) noexcept
607
      : store(static_cast<wasm_store_t *>(s)), category(ref.category),
608
        inner(ref.inner), info(ref.info), finalizer(ref.finalizer) {
609
    increase_ref();
610
  }
611
  // No unlink() here — destroy() calls decrease_ref() explicitly to avoid
612
  // recursing through the destructor chain.
613
  ~wasm_ref_base_t() noexcept = default;
614
0
  void decrease_ref() noexcept {
615
0
    store->allocmgr.unlink<C>(static_cast<C *>(inner));
616
0
  }
Unexecuted instantiation: wasm_ref_base_t<wasm_ref_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_trap_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_foreign_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_module_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_func_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_global_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_table_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_memory_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_extern_t>::decrease_ref()
Unexecuted instantiation: wasm_ref_base_t<wasm_instance_t>::decrease_ref()
617
0
  void increase_ref() const noexcept {
618
0
    store->allocmgr.link<C>(static_cast<C *>(inner));
619
0
  }
Unexecuted instantiation: wasm_ref_base_t<wasm_trap_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_module_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_func_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_foreign_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_global_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_table_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_memory_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_instance_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_ref_t>::increase_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_extern_t>::increase_ref() const
620
0
  wasm::own<C> copy_ref() const noexcept {
621
0
    increase_ref();
622
0
    return wasm::make_own<C>(static_cast<C *>(inner));
623
0
  }
Unexecuted instantiation: wasm_ref_base_t<wasm_ref_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_trap_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_foreign_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_module_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_func_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_global_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_table_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_memory_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_extern_t>::copy_ref() const
Unexecuted instantiation: wasm_ref_base_t<wasm_instance_t>::copy_ref() const
624
625
  wasm_store_t *store;
626
  wasm_category_enum category;
627
  void *inner;
628
  void *info;
629
  void (*finalizer)(void *);
630
};
631
632
// wasm_ref_t implementation. wasm::X is the first base (EBO'd to size 0)
633
// in every ref-bearing concrete type, so wasm_ref_base_t<C> lands at offset 0.
634
struct wasm_ref_t : public wasm::Ref, public wasm_ref_base_t<wasm_ref_t> {
635
  wasm_ref_t() = delete;
636
};
637
638
// wasm_frame_t implementation. funcoff / moduleoff are kept for the spec
639
// API surface but stay 0 until the engine exposes address-map info.
640
struct wasm_frame_t : public wasm::Frame {
641
  explicit wasm_frame_t(uint32_t idx) noexcept
642
0
      : funcidx(idx), funcoff(0), moduleoff(0) {}
643
  wasm_frame_t(const wasm_frame_t &) noexcept = default;
644
  wasm_frame_t &operator=(const wasm_frame_t &) noexcept = default;
645
  uint32_t funcidx;
646
  size_t funcoff;
647
  size_t moduleoff;
648
};
649
650
// wasm_trap_t implementation. morigin holds the outermost called funcidx;
651
// deeper frames and offsets are unavailable from the engine.
652
struct wasm_trap_t : public wasm::Trap, wasm_ref_base_t<wasm_trap_t> {
653
  wasm_trap_t(wasm::Store *s, wasm::Message &&m,
654
              wasm_frame_t origin = wasm_frame_t(0)) noexcept
655
0
      : wasm_ref_base_t<wasm_trap_t>(s), mmsg(std::move(m)), morigin(origin) {}
656
  wasm::Message mmsg;
657
  wasm_frame_t morigin;
658
};
659
660
// wasm_foreign_t implementation.
661
// TODO: the foreign object is not supported yet.
662
struct wasm_foreign_t : public wasm::Foreign, wasm_ref_base_t<wasm_foreign_t> {
663
  wasm_foreign_t(wasm::Store *s) noexcept
664
0
      : wasm_ref_base_t<wasm_foreign_t>(s) {}
665
};
666
667
// wasm_module_t implementation.
668
struct wasm_module_t : public wasm::Module, wasm_ref_base_t<wasm_module_t> {
669
  wasm_module_t(wasm::Store *s, std::unique_ptr<WasmEdge::AST::Module> &&mod,
670
                wasm::vec<byte_t> &&bin) noexcept
671
0
      : wasm_ref_base_t<wasm_module_t>(s), ast(std::move(mod)),
672
0
        binary(std::move(bin)) {}
673
  std::unique_ptr<WasmEdge::AST::Module> ast;
674
  wasm::vec<byte_t> binary;
675
};
676
677
// wasm_shared_module_t implementation.
678
struct wasm_shared_module_t : public wasm::Shared<wasm::Module> {
679
  // Currently, the shared object is only used in modules.
680
  // Therefore we can use the serialize/deserialize mechanism to share and
681
  // obtain the object here. If there are other types of shared objects in the
682
  // future, the implementations should be updated.
683
  wasm_shared_module_t(wasm::vec<byte_t> &&bin) noexcept
684
0
      : binary(std::move(bin)) {}
685
  wasm::vec<byte_t> binary;
686
};
687
688
// wasm_extern_t implementation. Never instantiated; only a layout shim so
689
// static_cast from wasm::Extern * finds mkind at the same offset as the
690
// other wasm_X_t extern types.
691
struct wasm_extern_t : public wasm::Extern,
692
                       public wasm_ref_base_t<wasm_extern_t> {
693
  const wasm::ExternKind mkind;
694
  wasm_extern_t() = delete;
695
};
696
697
// wasm_func_t implementation.
698
struct wasm_func_t : public wasm::Func, public wasm_ref_base_t<wasm_func_t> {
699
  wasm_func_t(wasm::Store *s, const wasm::FuncType &ft,
700
              wasm_func_callback_t cb) noexcept
701
0
      : wasm_ref_base_t<wasm_func_t>(s), owned(true) {
702
0
    inst = new WasmEdge::Runtime::Instance::FunctionInstance(
703
0
        std::make_unique<wasm_hostfunc_t>(ft, cb));
704
0
  }
705
  wasm_func_t(wasm::Store *s, const wasm::FuncType &ft,
706
              wasm_func_callback_with_env_t cb, void *env,
707
              void (*fin)(void *)) noexcept
708
0
      : wasm_ref_base_t<wasm_func_t>(s), owned(true) {
709
0
    inst = new WasmEdge::Runtime::Instance::FunctionInstance(
710
0
        std::make_unique<wasm_hostfunc_t>(ft, cb, env, fin));
711
0
  }
712
  wasm_func_t(wasm::Store *s, const wasm::FuncType &ft,
713
              wasm::Func::callback cb) noexcept
714
0
      : wasm_ref_base_t<wasm_func_t>(s), owned(true) {
715
0
    inst = new WasmEdge::Runtime::Instance::FunctionInstance(
716
0
        std::make_unique<wasm_hostfunc_t>(ft, cb));
717
0
  }
718
  wasm_func_t(wasm::Store *s, const wasm::FuncType &ft,
719
              wasm::Func::callback_with_env cb, void *env,
720
              void (*fin)(void *)) noexcept
721
0
      : wasm_ref_base_t<wasm_func_t>(s), owned(true) {
722
0
    inst = new WasmEdge::Runtime::Instance::FunctionInstance(
723
0
        std::make_unique<wasm_hostfunc_t>(ft, cb, env, fin));
724
0
  }
725
  // Non-owning view (for wasm_instance_exports / wasm_table_get funcref).
726
  wasm_func_t(wasm::Store *s,
727
              WasmEdge::Runtime::Instance::FunctionInstance *fi) noexcept
728
0
      : wasm_ref_base_t<wasm_func_t>(s), owned(false) {
729
0
    inst = fi;
730
0
  }
731
0
  ~wasm_func_t() {
732
0
    if (owned && inst) {
733
0
      delete inst;
734
0
    }
735
0
  }
736
  const wasm::ExternKind mkind = wasm::ExternKind::FUNC;
737
  bool owned;
738
  WasmEdge::Runtime::Instance::FunctionInstance *inst;
739
};
740
741
// wasm_global_t implementation.
742
struct wasm_global_t : public wasm::Global,
743
                       public wasm_ref_base_t<wasm_global_t> {
744
  // Owning ctor (wasm_global_new).
745
  wasm_global_t(wasm::Store *s, const wasm::GlobalType &gt,
746
                const wasm::Val &v) noexcept
747
0
      : wasm_ref_base_t<wasm_global_t>(s), owned(true), keepval(v.copy()),
748
0
        inst(new WasmEdge::Runtime::Instance::GlobalInstance(
749
0
            WasmEdge::AST::GlobalType(
750
0
                conv_valtype_to_wasmedge(gt.content()->kind()),
751
0
                conv_valmut_to_wasmedge(gt.mutability())),
752
0
            conv_cppval_to_wasmedge(v))) {}
753
  // Non-owning view (wasm_instance_exports).
754
  wasm_global_t(wasm::Store *s,
755
                WasmEdge::Runtime::Instance::GlobalInstance *gi) noexcept
756
0
      : wasm_ref_base_t<wasm_global_t>(s), owned(false), inst(gi) {}
757
0
  ~wasm_global_t() {
758
0
    if (owned && inst) {
759
0
      delete inst;
760
0
    }
761
0
  }
762
  const wasm::ExternKind mkind = wasm::ExternKind::GLOBAL;
763
  bool owned;
764
  // Copy the init val to keep the reference if the valtype is a ref.
765
  wasm::Val keepval;
766
  WasmEdge::Runtime::Instance::GlobalInstance *inst;
767
};
768
769
// wasm_table_t implementation.
770
struct wasm_table_t : public wasm::Table, public wasm_ref_base_t<wasm_table_t> {
771
  // Owning ctor (wasm_table_new).
772
  wasm_table_t(wasm::Store *s, const wasm::TableType &tt,
773
               const wasm::Ref *r) noexcept
774
0
      : wasm_ref_base_t<wasm_table_t>(s), owned(true),
775
0
        inst(new WasmEdge::Runtime::Instance::TableInstance(
776
0
            WasmEdge::AST::TableType(
777
0
                conv_reftype_to_wasmedge(tt.element()->kind()), tt.limits().min,
778
0
                tt.limits().max))) {
779
0
    if (inst->getTableType().getRefType().isFuncRefType()) {
780
0
      if (r && static_cast<const wasm_ref_t *>(r)->category ==
781
0
                   wasm_category_enum::FUNC) {
782
0
        inst->fillRefs(
783
0
            WasmEdge::RefVariant(static_cast<const wasm_func_t *>(r)->inst), 0,
784
0
            inst->getSize());
785
0
      } else {
786
0
        inst->fillRefs(WasmEdge::RefVariant(
787
0
                           WasmEdge::ValType(WasmEdge::TypeCode::FuncRef)),
788
0
                       0, inst->getSize());
789
0
      }
790
0
    } else {
791
0
      inst->fillRefs(WasmEdge::RefVariant(const_cast<wasm::Ref *>(r)), 0,
792
0
                     inst->getSize());
793
0
    }
794
0
  }
795
  // Non-owning view (wasm_instance_exports).
796
  wasm_table_t(wasm::Store *s,
797
               WasmEdge::Runtime::Instance::TableInstance *ti) noexcept
798
0
      : wasm_ref_base_t<wasm_table_t>(s), owned(false), inst(ti) {}
799
0
  ~wasm_table_t() {
800
0
    if (owned && inst) {
801
0
      delete inst;
802
0
    }
803
0
  }
804
  const wasm::ExternKind mkind = wasm::ExternKind::TABLE;
805
  bool owned;
806
  WasmEdge::Runtime::Instance::TableInstance *inst;
807
};
808
809
// wasm_memory_t implementation.
810
struct wasm_memory_t : public wasm::Memory,
811
                       public wasm_ref_base_t<wasm_memory_t> {
812
  // Owning ctor (wasm_memory_new).
813
  wasm_memory_t(wasm::Store *s, const wasm::MemoryType &mt) noexcept
814
0
      : wasm_ref_base_t<wasm_memory_t>(s), owned(true),
815
0
        inst(new WasmEdge::Runtime::Instance::MemoryInstance(
816
0
            WasmEdge::AST::MemoryType(mt.limits().min, mt.limits().max))) {}
817
  // Non-owning view (wasm_instance_exports).
818
  wasm_memory_t(wasm::Store *s,
819
                WasmEdge::Runtime::Instance::MemoryInstance *mi) noexcept
820
0
      : wasm_ref_base_t<wasm_memory_t>(s), owned(false), inst(mi) {}
821
0
  ~wasm_memory_t() {
822
0
    if (owned && inst) {
823
0
      delete inst;
824
0
    }
825
0
  }
826
  const wasm::ExternKind mkind = wasm::ExternKind::MEMORY;
827
  bool owned;
828
  WasmEdge::Runtime::Instance::MemoryInstance *inst;
829
};
830
831
// wasm_instance_t implementation.
832
struct wasm_instance_t : public wasm::Instance,
833
                         wasm_ref_base_t<wasm_instance_t> {
834
  // Captures export order at instantiation (ModuleInstance maps sort by name).
835
  struct export_entry_t {
836
    std::string name;
837
    WasmEdge::ExternalType kind;
838
  };
839
  wasm_instance_t(
840
      wasm::Store *s,
841
      std::unique_ptr<WasmEdge::Runtime::Instance::ModuleInstance> &&mi,
842
      std::vector<std::unique_ptr<wasm_import_module_t>> &&imps,
843
      std::vector<wasm::own<wasm::Extern>> &&retained,
844
      std::vector<export_entry_t> &&exps) noexcept
845
0
      : wasm_ref_base_t<wasm_instance_t>(s), exportorder(std::move(exps)),
846
0
        retainedImports(std::move(retained)), importmods(std::move(imps)),
847
0
        modinst(std::move(mi)) {}
848
  std::vector<export_entry_t> exportorder;
849
  // Keep host-provided imports alive for the instance's lifetime.
850
  std::vector<wasm::own<wasm::Extern>> retainedImports;
851
  std::vector<std::unique_ptr<wasm_import_module_t>> importmods;
852
  std::unique_ptr<WasmEdge::Runtime::Instance::ModuleInstance> modinst;
853
};
854
855
namespace {
856
857
// Reverse-lookup funcidx within fi's owning module; 0 if fi is a host
858
// function with no owner module or otherwise unresolvable.
859
uint32_t
860
0
lookupFuncIdx(const WasmEdge::Runtime::Instance::FunctionInstance *fi) {
861
0
  if (!fi) {
862
0
    return 0;
863
0
  }
864
0
  const auto *mi = fi->getModule();
865
0
  if (!mi) {
866
0
    return 0;
867
0
  }
868
0
  auto funcs = mi->getFunctionInstances();
869
0
  for (uint32_t i = 0; i < funcs.size(); ++i) {
870
0
    if (funcs[i] == fi) {
871
0
      return i;
872
0
    }
873
0
  }
874
0
  return 0;
875
0
}
876
877
wasm::own<wasm::Trap> buildTrap(wasm::Store *store,
878
                                const WasmEdge::ErrCode &code,
879
0
                                uint32_t originFuncIdx = 0) {
880
0
  auto msg = wasm::Message::make_nt(
881
0
      fmt::format("{} failed: {}, Code: 0x{:03x}", code.getErrCodePhase(),
882
0
                  WasmEdge::ErrCodeStr[code.getEnum()], code.getCode()));
883
0
  return wasm::make_own(new (std::nothrow) wasm_trap_t(
884
0
      store, std::move(msg), wasm_frame_t(originFuncIdx)));
885
0
}
886
887
// Global variables to prevent from new/delete.
888
wasm_valtype_t wasm_valtype_i32(wasm::ValKind::I32);
889
wasm_valtype_t wasm_valtype_i64(wasm::ValKind::I64);
890
wasm_valtype_t wasm_valtype_f32(wasm::ValKind::F32);
891
wasm_valtype_t wasm_valtype_f64(wasm::ValKind::F64);
892
wasm_valtype_t wasm_valtype_externref(wasm::ValKind::EXTERNREF);
893
wasm_valtype_t wasm_valtype_funcref(wasm::ValKind::FUNCREF);
894
895
// Helper macro for the C APIs to get attributtes.
896
#define WASM_DECLARE_C_GET_ATTR(name, target, attr, cast_type, def_val,        \
897
                                is_ref, is_const)                              \
898
  WASMEDGE_CAPI_EXPORT is_const target wasm_##name##_##attr(                   \
899
0
      const wasm_##name##_t *ptr) {                                            \
900
0
    if (ptr) {                                                                 \
901
0
      return cast_type##_cast<is_const target>(is_ref(ptr->attr()));           \
902
0
    }                                                                          \
903
0
    return def_val;                                                            \
904
0
  }
Unexecuted instantiation: wasm_valtype_kind
Unexecuted instantiation: wasm_functype_params
Unexecuted instantiation: wasm_functype_results
Unexecuted instantiation: wasm_globaltype_content
Unexecuted instantiation: wasm_globaltype_mutability
Unexecuted instantiation: wasm_tabletype_element
Unexecuted instantiation: wasm_tabletype_limits
Unexecuted instantiation: wasm_memorytype_limits
Unexecuted instantiation: wasm_tagtype_functype
Unexecuted instantiation: wasm_externtype_kind
Unexecuted instantiation: wasm_importtype_module
Unexecuted instantiation: wasm_importtype_name
Unexecuted instantiation: wasm_importtype_type
Unexecuted instantiation: wasm_exporttype_name
Unexecuted instantiation: wasm_exporttype_type
Unexecuted instantiation: wasm_frame_instance
Unexecuted instantiation: wasm_frame_func_index
Unexecuted instantiation: wasm_frame_func_offset
Unexecuted instantiation: wasm_frame_module_offset
Unexecuted instantiation: wasm_func_param_arity
Unexecuted instantiation: wasm_func_result_arity
Unexecuted instantiation: wasm_table_size
Unexecuted instantiation: wasm_memory_data_size
Unexecuted instantiation: wasm_memory_size
Unexecuted instantiation: wasm_extern_kind
905
906
// Helper macro for the WASM_DECLARE_OWN implementation.
907
#define WASM_DECLARE_OWN_IMPL(name, Name)                                      \
908
0
  WASMEDGE_CAPI_EXPORT void wasm_##name##_delete(OWN wasm_##name##_t *obj) {   \
909
0
    wasm::own<Name> ptr(obj);                                                  \
910
0
  }
Unexecuted instantiation: wasm_config_delete
Unexecuted instantiation: wasm_engine_delete
Unexecuted instantiation: wasm_store_delete
Unexecuted instantiation: wasm_valtype_delete
Unexecuted instantiation: wasm_functype_delete
Unexecuted instantiation: wasm_globaltype_delete
Unexecuted instantiation: wasm_tabletype_delete
Unexecuted instantiation: wasm_memorytype_delete
Unexecuted instantiation: wasm_tagtype_delete
Unexecuted instantiation: wasm_externtype_delete
Unexecuted instantiation: wasm_importtype_delete
Unexecuted instantiation: wasm_exporttype_delete
Unexecuted instantiation: wasm_ref_delete
Unexecuted instantiation: wasm_frame_delete
Unexecuted instantiation: wasm_trap_delete
Unexecuted instantiation: wasm_foreign_delete
Unexecuted instantiation: wasm_module_delete
Unexecuted instantiation: wasm_shared_module_delete
Unexecuted instantiation: wasm_func_delete
Unexecuted instantiation: wasm_global_delete
Unexecuted instantiation: wasm_table_delete
Unexecuted instantiation: wasm_memory_delete
Unexecuted instantiation: wasm_extern_delete
Unexecuted instantiation: wasm_instance_delete
911
912
// Helper macro for the base of WASM_DECLARE_VEC implementation.
913
#define WASM_DECLARE_VEC_BASE_IMPL(name, Name, ownvec, vec, ptr)               \
914
  WASMEDGE_CAPI_EXPORT void wasm_##name##_vec_new_uninitialized(               \
915
0
      OWN wasm_##name##_vec_t *out, size_t size) {                             \
916
0
    if (out) {                                                                 \
917
0
      if (size < UINT32_MAX) {                                                 \
918
0
        auto v = ownvec<Name>::make_uninitialized(size);                       \
919
0
        out->size = v.size();                                                  \
920
0
        out->data = reinterpret_cast<wasm_##name##_t ptr *>(v.release());      \
921
0
      } else {                                                                 \
922
0
        out->size = 0;                                                         \
923
0
        out->data = nullptr;                                                   \
924
0
      }                                                                        \
925
0
    }                                                                          \
926
0
  }                                                                            \
927
  WASMEDGE_CAPI_EXPORT void wasm_##name##_vec_new_empty(                       \
928
0
      OWN wasm_##name##_vec_t *out) {                                          \
929
0
    wasm_##name##_vec_new_uninitialized(out, 0);                               \
930
0
  }                                                                            \
Unexecuted instantiation: wasm_byte_vec_new_empty
Unexecuted instantiation: wasm_valtype_vec_new_empty
Unexecuted instantiation: wasm_functype_vec_new_empty
Unexecuted instantiation: wasm_globaltype_vec_new_empty
Unexecuted instantiation: wasm_tabletype_vec_new_empty
Unexecuted instantiation: wasm_memorytype_vec_new_empty
Unexecuted instantiation: wasm_tagtype_vec_new_empty
Unexecuted instantiation: wasm_externtype_vec_new_empty
Unexecuted instantiation: wasm_importtype_vec_new_empty
Unexecuted instantiation: wasm_exporttype_vec_new_empty
Unexecuted instantiation: wasm_val_vec_new_empty
Unexecuted instantiation: wasm_frame_vec_new_empty
Unexecuted instantiation: wasm_extern_vec_new_empty
931
  WASMEDGE_CAPI_EXPORT void wasm_##name##_vec_delete(                          \
932
0
      OWN wasm_##name##_vec_t *v) {                                            \
933
0
    if (v) {                                                                   \
934
0
      ownvec<Name>::adopt(                                                     \
935
0
          v->size, reinterpret_cast<ownvec<Name>::elem_type *>(v->data));      \
936
0
      v->size = 0;                                                             \
937
0
      v->data = nullptr;                                                       \
938
0
    }                                                                          \
939
0
  }
Unexecuted instantiation: wasm_byte_vec_delete
Unexecuted instantiation: wasm_valtype_vec_delete
Unexecuted instantiation: wasm_functype_vec_delete
Unexecuted instantiation: wasm_globaltype_vec_delete
Unexecuted instantiation: wasm_tabletype_vec_delete
Unexecuted instantiation: wasm_memorytype_vec_delete
Unexecuted instantiation: wasm_tagtype_vec_delete
Unexecuted instantiation: wasm_externtype_vec_delete
Unexecuted instantiation: wasm_importtype_vec_delete
Unexecuted instantiation: wasm_exporttype_vec_delete
Unexecuted instantiation: wasm_val_vec_delete
Unexecuted instantiation: wasm_frame_vec_delete
Unexecuted instantiation: wasm_extern_vec_delete
940
941
// Helper macro for the parts of WASM_DECLARE_VEC implementation.
942
#define WASM_DECLARE_VEC_SCALAR_IMPL(name, Name)                               \
943
  WASM_DECLARE_VEC_BASE_IMPL(name, Name, wasm::vec, wasm::vec, )               \
944
  WASMEDGE_CAPI_EXPORT void wasm_##name##_vec_new(                             \
945
      OWN wasm_##name##_vec_t *out, size_t size,                               \
946
0
      OWN wasm_##name##_t const vals[]) {                                      \
947
0
    if (out) {                                                                 \
948
0
      *out = {0, nullptr};                                                     \
949
0
      if (size < UINT32_MAX) {                                                 \
950
0
        auto v = wasm::vec<Name>::make_uninitialized(size);                    \
951
0
        if (v.size() > 0) {                                                    \
952
0
          std::copy_n(vals, size, v.get());                                    \
953
0
        }                                                                      \
954
0
        *out = {v.size(), reinterpret_cast<wasm_##name##_t *>(v.release())};   \
955
0
      }                                                                        \
956
0
    }                                                                          \
957
0
  }                                                                            \
958
  WASMEDGE_CAPI_EXPORT void wasm_##name##_vec_copy(                            \
959
0
      OWN wasm_##name##_vec_t *out, const wasm_##name##_vec_t *in) {           \
960
0
    if (out) {                                                                 \
961
0
      *out = {0, nullptr};                                                     \
962
0
    }                                                                          \
963
0
    if (in && out) {                                                           \
964
0
      wasm_##name##_vec_new(out, in->size, in->data);                          \
965
0
    }                                                                          \
966
0
  }
967
968
// Helper macro for the parts of WASM_DECLARE_VEC implementation.
969
#define WASM_DECLARE_VEC_PTR_IMPL(name, Name)                                  \
970
  WASM_DECLARE_VEC_BASE_IMPL(name, Name, wasm::ownvec, wasm::vec, *)           \
971
  WASMEDGE_CAPI_EXPORT void wasm_##name##_vec_new(                             \
972
      OWN wasm_##name##_vec_t *out, size_t size,                               \
973
0
      OWN wasm_##name##_t *const data[]) {                                     \
974
0
    if (out) {                                                                 \
975
0
      *out = {0, nullptr};                                                     \
976
0
      if (size < UINT32_MAX) {                                                 \
977
0
        auto v = wasm::ownvec<Name>::make_uninitialized(size);                 \
978
0
        for (size_t i = 0; i < v.size(); ++i) {                                \
979
0
          v[i] = wasm::make_own(data[i]);                                      \
980
0
        }                                                                      \
981
0
        *out = {v.size(), reinterpret_cast<wasm_##name##_t **>(v.release())};  \
982
0
      }                                                                        \
983
0
    }                                                                          \
984
0
  }                                                                            \
985
  WASMEDGE_CAPI_EXPORT void wasm_##name##_vec_copy(                            \
986
0
      OWN wasm_##name##_vec_t *out, const wasm_##name##_vec_t *in) {           \
987
0
    if (out) {                                                                 \
988
0
      *out = {0, nullptr};                                                     \
989
0
    }                                                                          \
990
0
    if (in && out && in->size < UINT32_MAX) {                                  \
991
0
      auto v = wasm::ownvec<Name>::make_uninitialized(in->size);               \
992
0
      for (size_t i = 0; i < v.size(); ++i) {                                  \
993
0
        v[i] = wasm::make_own(wasm_##name##_copy(in->data[i]));                \
994
0
      }                                                                        \
995
0
      *out = {v.size(), reinterpret_cast<wasm_##name##_t **>(v.release())};    \
996
0
    }                                                                          \
997
0
  }
998
999
// Helper macro for the WASM_DECLARE_TYPE implementation.
1000
#define WASM_DECLARE_TYPE_IMPL(name, Name)                                     \
1001
  WASM_DECLARE_OWN_IMPL(name, Name)                                            \
1002
  WASM_DECLARE_VEC_PTR_IMPL(name, Name)                                        \
1003
  WASMEDGE_CAPI_EXPORT wasm_##name##_t OWN *wasm_##name##_copy(                \
1004
0
      const wasm_##name##_t *inst) {                                           \
1005
0
    if (inst) {                                                                \
1006
0
      return static_cast<wasm_##name##_t *>((inst->copy()).release());         \
1007
0
    }                                                                          \
1008
0
    return nullptr;                                                            \
1009
0
  }
Unexecuted instantiation: wasm_valtype_copy
Unexecuted instantiation: wasm_functype_copy
Unexecuted instantiation: wasm_globaltype_copy
Unexecuted instantiation: wasm_tabletype_copy
Unexecuted instantiation: wasm_memorytype_copy
Unexecuted instantiation: wasm_tagtype_copy
Unexecuted instantiation: wasm_externtype_copy
Unexecuted instantiation: wasm_importtype_copy
Unexecuted instantiation: wasm_exporttype_copy
1010
1011
// Helper macro for the base of WASM_DECLARE_REF implementation.
1012
#define WASM_DECLARE_REF_BASE_IMPL(name, Name)                                 \
1013
  WASM_DECLARE_OWN_IMPL(name, Name)                                            \
1014
  WASMEDGE_CAPI_EXPORT OWN wasm_##name##_t *wasm_##name##_copy(                \
1015
0
      const wasm_##name##_t *t) {                                              \
1016
0
    return static_cast<wasm_##name##_t *>(t->copy().release());                \
1017
0
  }                                                                            \
Unexecuted instantiation: wasm_ref_copy
Unexecuted instantiation: wasm_trap_copy
Unexecuted instantiation: wasm_foreign_copy
Unexecuted instantiation: wasm_module_copy
Unexecuted instantiation: wasm_func_copy
Unexecuted instantiation: wasm_global_copy
Unexecuted instantiation: wasm_table_copy
Unexecuted instantiation: wasm_memory_copy
Unexecuted instantiation: wasm_extern_copy
Unexecuted instantiation: wasm_instance_copy
1018
  WASMEDGE_CAPI_EXPORT bool wasm_##name##_same(const wasm_##name##_t *t1,      \
1019
0
                                               const wasm_##name##_t *t2) {    \
1020
0
    return t1->same(t2);                                                       \
1021
0
  }                                                                            \
Unexecuted instantiation: wasm_ref_same
Unexecuted instantiation: wasm_trap_same
Unexecuted instantiation: wasm_foreign_same
Unexecuted instantiation: wasm_module_same
Unexecuted instantiation: wasm_func_same
Unexecuted instantiation: wasm_global_same
Unexecuted instantiation: wasm_table_same
Unexecuted instantiation: wasm_memory_same
Unexecuted instantiation: wasm_extern_same
Unexecuted instantiation: wasm_instance_same
1022
  WASMEDGE_CAPI_EXPORT void *wasm_##name##_get_host_info(                      \
1023
0
      const wasm_##name##_t *r) {                                              \
1024
0
    return r->get_host_info();                                                 \
1025
0
  }                                                                            \
Unexecuted instantiation: wasm_ref_get_host_info
Unexecuted instantiation: wasm_trap_get_host_info
Unexecuted instantiation: wasm_foreign_get_host_info
Unexecuted instantiation: wasm_module_get_host_info
Unexecuted instantiation: wasm_func_get_host_info
Unexecuted instantiation: wasm_global_get_host_info
Unexecuted instantiation: wasm_table_get_host_info
Unexecuted instantiation: wasm_memory_get_host_info
Unexecuted instantiation: wasm_extern_get_host_info
Unexecuted instantiation: wasm_instance_get_host_info
1026
  WASMEDGE_CAPI_EXPORT void wasm_##name##_set_host_info(wasm_##name##_t *r,    \
1027
0
                                                        void *info) {          \
1028
0
    r->set_host_info(info);                                                    \
1029
0
  }                                                                            \
Unexecuted instantiation: wasm_ref_set_host_info
Unexecuted instantiation: wasm_trap_set_host_info
Unexecuted instantiation: wasm_foreign_set_host_info
Unexecuted instantiation: wasm_module_set_host_info
Unexecuted instantiation: wasm_func_set_host_info
Unexecuted instantiation: wasm_global_set_host_info
Unexecuted instantiation: wasm_table_set_host_info
Unexecuted instantiation: wasm_memory_set_host_info
Unexecuted instantiation: wasm_extern_set_host_info
Unexecuted instantiation: wasm_instance_set_host_info
1030
  WASMEDGE_CAPI_EXPORT void wasm_##name##_set_host_info_with_finalizer(        \
1031
0
      wasm_##name##_t *r, void *info, void (*finalizer)(void *)) {             \
1032
0
    r->set_host_info(info, finalizer);                                         \
1033
0
  }
Unexecuted instantiation: wasm_ref_set_host_info_with_finalizer
Unexecuted instantiation: wasm_trap_set_host_info_with_finalizer
Unexecuted instantiation: wasm_foreign_set_host_info_with_finalizer
Unexecuted instantiation: wasm_module_set_host_info_with_finalizer
Unexecuted instantiation: wasm_func_set_host_info_with_finalizer
Unexecuted instantiation: wasm_global_set_host_info_with_finalizer
Unexecuted instantiation: wasm_table_set_host_info_with_finalizer
Unexecuted instantiation: wasm_memory_set_host_info_with_finalizer
Unexecuted instantiation: wasm_extern_set_host_info_with_finalizer
Unexecuted instantiation: wasm_instance_set_host_info_with_finalizer
1034
1035
// Helper macro for the WASM_DECLARE_REF implementation.
1036
#define WASM_DECLARE_REF_IMPL(name, Name)                                      \
1037
  WASM_DECLARE_REF_BASE_IMPL(name, Name)                                       \
1038
0
  WASMEDGE_CAPI_EXPORT wasm_ref_t *wasm_##name##_as_ref(wasm_##name##_t *r) {  \
1039
0
    return static_cast<wasm_ref_t *>(                                          \
1040
0
        static_cast<wasm::Ref *>(static_cast<Name *>(r)));                     \
1041
0
  }                                                                            \
Unexecuted instantiation: wasm_trap_as_ref
Unexecuted instantiation: wasm_foreign_as_ref
Unexecuted instantiation: wasm_module_as_ref
Unexecuted instantiation: wasm_func_as_ref
Unexecuted instantiation: wasm_global_as_ref
Unexecuted instantiation: wasm_table_as_ref
Unexecuted instantiation: wasm_memory_as_ref
Unexecuted instantiation: wasm_extern_as_ref
Unexecuted instantiation: wasm_instance_as_ref
1042
0
  WASMEDGE_CAPI_EXPORT wasm_##name##_t *wasm_ref_as_##name(wasm_ref_t *r) {    \
1043
0
    return static_cast<wasm_##name##_t *>(                                     \
1044
0
        static_cast<Name *>(static_cast<wasm::Ref *>(r)));                     \
1045
0
  }                                                                            \
Unexecuted instantiation: wasm_ref_as_trap
Unexecuted instantiation: wasm_ref_as_foreign
Unexecuted instantiation: wasm_ref_as_module
Unexecuted instantiation: wasm_ref_as_func
Unexecuted instantiation: wasm_ref_as_global
Unexecuted instantiation: wasm_ref_as_table
Unexecuted instantiation: wasm_ref_as_memory
Unexecuted instantiation: wasm_ref_as_extern
Unexecuted instantiation: wasm_ref_as_instance
1046
  WASMEDGE_CAPI_EXPORT const wasm_ref_t *wasm_##name##_as_ref_const(           \
1047
0
      const wasm_##name##_t *r) {                                              \
1048
0
    return static_cast<const wasm_ref_t *>(                                    \
1049
0
        static_cast<const wasm::Ref *>(static_cast<const Name *>(r)));         \
1050
0
  }                                                                            \
Unexecuted instantiation: wasm_trap_as_ref_const
Unexecuted instantiation: wasm_foreign_as_ref_const
Unexecuted instantiation: wasm_module_as_ref_const
Unexecuted instantiation: wasm_func_as_ref_const
Unexecuted instantiation: wasm_global_as_ref_const
Unexecuted instantiation: wasm_table_as_ref_const
Unexecuted instantiation: wasm_memory_as_ref_const
Unexecuted instantiation: wasm_extern_as_ref_const
Unexecuted instantiation: wasm_instance_as_ref_const
1051
  WASMEDGE_CAPI_EXPORT const wasm_##name##_t *wasm_ref_as_##name##_const(      \
1052
0
      const wasm_ref_t *r) {                                                   \
1053
0
    return static_cast<const wasm_##name##_t *>(                               \
1054
0
        static_cast<const Name *>(static_cast<const wasm::Ref *>(r)));         \
1055
0
  }
Unexecuted instantiation: wasm_ref_as_trap_const
Unexecuted instantiation: wasm_ref_as_foreign_const
Unexecuted instantiation: wasm_ref_as_module_const
Unexecuted instantiation: wasm_ref_as_func_const
Unexecuted instantiation: wasm_ref_as_global_const
Unexecuted instantiation: wasm_ref_as_table_const
Unexecuted instantiation: wasm_ref_as_memory_const
Unexecuted instantiation: wasm_ref_as_extern_const
Unexecuted instantiation: wasm_ref_as_instance_const
1056
1057
// Helper macro for the WASM_DECLARE_SHARABLE_REF implementation.
1058
#define WASM_DECLARE_SHARABLE_REF_IMPL(name, Name)                             \
1059
  WASM_DECLARE_REF_IMPL(name, Name)                                            \
1060
  WASM_DECLARE_OWN_IMPL(shared_##name, wasm::Shared<wasm::Module>)
1061
1062
// Helper macro for the wasm_externtype_t and wasm_extern_t conversions.
1063
#define WASM_EXTERNTYPE_C_CONV(in, out, type, Type, connect, const_quant)      \
1064
  WASMEDGE_CAPI_EXPORT const_quant wasm_##out##type##_t *                      \
1065
  wasm_##in##type##_as_##out##type##connect##const_quant(                      \
1066
0
      const_quant wasm_##in##type##_t *ptr) {                                  \
1067
0
    return static_cast<const_quant wasm_##out##type##_t *>(                    \
1068
0
        static_cast<const_quant wasm::Extern##Type *>(ptr));                   \
1069
0
  }
Unexecuted instantiation: wasm_functype_as_externtype
Unexecuted instantiation: wasm_functype_as_externtype_const
Unexecuted instantiation: wasm_globaltype_as_externtype
Unexecuted instantiation: wasm_globaltype_as_externtype_const
Unexecuted instantiation: wasm_tabletype_as_externtype
Unexecuted instantiation: wasm_tabletype_as_externtype_const
Unexecuted instantiation: wasm_memorytype_as_externtype
Unexecuted instantiation: wasm_memorytype_as_externtype_const
Unexecuted instantiation: wasm_tagtype_as_externtype
Unexecuted instantiation: wasm_tagtype_as_externtype_const
Unexecuted instantiation: wasm_externtype_as_functype
Unexecuted instantiation: wasm_externtype_as_functype_const
Unexecuted instantiation: wasm_externtype_as_globaltype
Unexecuted instantiation: wasm_externtype_as_globaltype_const
Unexecuted instantiation: wasm_externtype_as_tabletype
Unexecuted instantiation: wasm_externtype_as_tabletype_const
Unexecuted instantiation: wasm_externtype_as_memorytype
Unexecuted instantiation: wasm_externtype_as_memorytype_const
Unexecuted instantiation: wasm_externtype_as_tagtype
Unexecuted instantiation: wasm_externtype_as_tagtype_const
Unexecuted instantiation: wasm_func_as_extern
Unexecuted instantiation: wasm_func_as_extern_const
Unexecuted instantiation: wasm_global_as_extern
Unexecuted instantiation: wasm_global_as_extern_const
Unexecuted instantiation: wasm_table_as_extern
Unexecuted instantiation: wasm_table_as_extern_const
Unexecuted instantiation: wasm_memory_as_extern
Unexecuted instantiation: wasm_memory_as_extern_const
Unexecuted instantiation: wasm_extern_as_func
Unexecuted instantiation: wasm_extern_as_func_const
Unexecuted instantiation: wasm_extern_as_global
Unexecuted instantiation: wasm_extern_as_global_const
Unexecuted instantiation: wasm_extern_as_table
Unexecuted instantiation: wasm_extern_as_table_const
Unexecuted instantiation: wasm_extern_as_memory
Unexecuted instantiation: wasm_extern_as_memory_const
1070
1071
// Helper macro for the wasm::ExternType and wasm::Extern conversions.
1072
#define WASM_EXTERNTYPE_CPP_CONV(name, Name, Type, enum, const_quant)          \
1073
0
  const_quant wasm::Name##Type *wasm::Extern##Type::name() const_quant {       \
1074
0
    if (kind() == wasm::ExternKind::enum) {                                    \
1075
0
      return static_cast<const_quant wasm::Name##Type *>(this);                \
1076
0
    }                                                                          \
1077
0
    return nullptr;                                                            \
1078
0
  }
Unexecuted instantiation: wasm::ExternType::func()
Unexecuted instantiation: wasm::ExternType::func() const
Unexecuted instantiation: wasm::ExternType::global()
Unexecuted instantiation: wasm::ExternType::global() const
Unexecuted instantiation: wasm::ExternType::table()
Unexecuted instantiation: wasm::ExternType::table() const
Unexecuted instantiation: wasm::ExternType::memory()
Unexecuted instantiation: wasm::ExternType::memory() const
Unexecuted instantiation: wasm::ExternType::tag()
Unexecuted instantiation: wasm::ExternType::tag() const
Unexecuted instantiation: wasm::Extern::func()
Unexecuted instantiation: wasm::Extern::func() const
Unexecuted instantiation: wasm::Extern::global()
Unexecuted instantiation: wasm::Extern::global() const
Unexecuted instantiation: wasm::Extern::table()
Unexecuted instantiation: wasm::Extern::table() const
Unexecuted instantiation: wasm::Extern::memory()
Unexecuted instantiation: wasm::Extern::memory() const
1079
1080
0
inline wasm::Val conv_val_to_cpp(const wasm_val_t &v) {
1081
0
  switch (v.kind) {
1082
0
  case wasm_valkind_enum::WASM_I32:
1083
0
    return wasm::Val(v.of.i32);
1084
0
  case wasm_valkind_enum::WASM_I64:
1085
0
    return wasm::Val(v.of.i64);
1086
0
  case wasm_valkind_enum::WASM_F32:
1087
0
    return wasm::Val(v.of.f32);
1088
0
  case wasm_valkind_enum::WASM_F64:
1089
0
    return wasm::Val(v.of.f64);
1090
0
  case wasm_valkind_enum::WASM_EXTERNREF:
1091
0
  case wasm_valkind_enum::WASM_FUNCREF: {
1092
0
    if (v.of.ref) {
1093
0
      return wasm::Val(v.of.ref->copy_ref());
1094
0
    }
1095
0
    return wasm::Val();
1096
0
  }
1097
0
  default:
1098
0
    assumingUnreachable();
1099
0
  }
1100
0
}
1101
1102
0
inline wasm_val_t conv_val_to_c(const wasm::Val &v) {
1103
0
  wasm_val_t r;
1104
0
  switch (v.kind()) {
1105
0
  case wasm::ValKind::I32:
1106
0
    r.kind = wasm_valkind_enum::WASM_I32;
1107
0
    r.of.i32 = v.i32();
1108
0
    break;
1109
0
  case wasm::ValKind::I64:
1110
0
    r.kind = wasm_valkind_enum::WASM_I64;
1111
0
    r.of.i64 = v.i64();
1112
0
    break;
1113
0
  case wasm::ValKind::F32:
1114
0
    r.kind = wasm_valkind_enum::WASM_F32;
1115
0
    r.of.f32 = v.f32();
1116
0
    break;
1117
0
  case wasm::ValKind::F64:
1118
0
    r.kind = wasm_valkind_enum::WASM_F64;
1119
0
    r.of.f64 = v.f64();
1120
0
    break;
1121
0
  case wasm::ValKind::FUNCREF:
1122
0
    r.kind = wasm_valkind_enum::WASM_FUNCREF;
1123
0
    r.of.ref = static_cast<wasm_ref_t *>(v.ref());
1124
0
    break;
1125
0
  case wasm::ValKind::EXTERNREF:
1126
0
    r.kind = wasm_valkind_enum::WASM_EXTERNREF;
1127
0
    r.of.ref = static_cast<wasm_ref_t *>(v.ref());
1128
0
    break;
1129
0
  default:
1130
0
    assumingUnreachable();
1131
0
  }
1132
0
  return r;
1133
0
}
1134
1135
// WasmEdge::ValVariant to wasm_val_t conversion.
1136
wasm_val_t conv_cval_from_wasmedge(const WasmEdge::ValVariant &v,
1137
0
                                   const WasmEdge::ValType &vt) {
1138
  // Note: the conversion will not add the ref count of wasm_ref_t.
1139
0
  wasm_val_t r{};
1140
0
  if (vt.isNumType()) {
1141
0
    switch (vt.getCode()) {
1142
0
    case WasmEdge::TypeCode::I32:
1143
0
      r.kind = wasm_valkind_enum::WASM_I32;
1144
0
      r.of.i32 = static_cast<int32_t>(v.get<uint32_t>());
1145
0
      return r;
1146
0
    case WasmEdge::TypeCode::I64:
1147
0
      r.kind = wasm_valkind_enum::WASM_I64;
1148
0
      r.of.i64 = static_cast<int64_t>(v.get<uint64_t>());
1149
0
      return r;
1150
0
    case WasmEdge::TypeCode::F32:
1151
0
      r.kind = wasm_valkind_enum::WASM_F32;
1152
0
      r.of.f32 = v.get<float>();
1153
0
      return r;
1154
0
    case WasmEdge::TypeCode::F64:
1155
0
      r.kind = wasm_valkind_enum::WASM_F64;
1156
0
      r.of.f64 = v.get<double>();
1157
0
      return r;
1158
0
    default:
1159
0
      break;
1160
0
    }
1161
0
  } else if (vt.isFuncRefType()) {
1162
0
    r.kind = wasm_valkind_enum::WASM_FUNCREF;
1163
    // TODO: implement this
1164
0
    return r;
1165
0
  } else if (vt.isExternRefType()) {
1166
0
    r.kind = wasm_valkind_enum::WASM_EXTERNREF;
1167
0
    r.of.ref = v.get<WasmEdge::RefVariant>().getPtr<wasm_ref_t>();
1168
0
    return r;
1169
0
  }
1170
  // v128 and other types are not supported in wasm C API yet.
1171
0
  assumingUnreachable();
1172
0
}
1173
1174
// WasmEdge::ValVariant to wasm::Val conversion.
1175
wasm::Val conv_cppval_from_wasmedge(const WasmEdge::ValVariant &v,
1176
0
                                    const WasmEdge::ValType &vt) {
1177
  // Note: the conversion will add the ref count of wasm::Ref to make the
1178
  // wasm::Val.
1179
0
  if (vt.isNumType()) {
1180
0
    switch (vt.getCode()) {
1181
0
    case WasmEdge::TypeCode::I32:
1182
0
      return wasm::Val::i32(static_cast<int32_t>(v.get<uint32_t>()));
1183
0
    case WasmEdge::TypeCode::I64:
1184
0
      return wasm::Val::i64(static_cast<int64_t>(v.get<uint64_t>()));
1185
0
    case WasmEdge::TypeCode::F32:
1186
0
      return wasm::Val::f32(v.get<float>());
1187
0
    case WasmEdge::TypeCode::F64:
1188
0
      return wasm::Val::f64(v.get<double>());
1189
0
    default:
1190
0
      break;
1191
0
    }
1192
0
  } else if (vt.isFuncRefType()) {
1193
    // TODO: implement this
1194
0
    return wasm::Val();
1195
0
  } else if (vt.isExternRefType()) {
1196
0
    auto *ref = v.get<WasmEdge::RefVariant>().getPtr<wasm_ref_t>();
1197
0
    return wasm::Val::ref(ref ? ref->copy_ref() : wasm::own<wasm_ref_t>());
1198
0
  }
1199
  // v128 and other types are not supported in wasm C API yet.
1200
0
  assumingUnreachable();
1201
0
}
1202
1203
// wasm_val_t to WasmEdge::ValVariant conversion.
1204
0
WasmEdge::ValVariant conv_cval_to_wasmedge(const wasm_val_t &v) {
1205
  // Note: the conversion will not transfer the ownership of wasm_ref_t*.
1206
0
  switch (v.kind) {
1207
0
  case wasm_valkind_enum::WASM_I32:
1208
0
    return v.of.i32;
1209
0
  case wasm_valkind_enum::WASM_I64:
1210
0
    return v.of.i64;
1211
0
  case wasm_valkind_enum::WASM_F32:
1212
0
    return v.of.f32;
1213
0
  case wasm_valkind_enum::WASM_F64:
1214
0
    return v.of.f64;
1215
0
  case wasm_valkind_enum::WASM_EXTERNREF:
1216
0
    return WasmEdge::RefVariant(v.of.ref);
1217
0
  case wasm_valkind_enum::WASM_FUNCREF:
1218
0
    if (v.of.ref && v.of.ref->category == wasm_category_enum::FUNC) {
1219
0
      return WasmEdge::RefVariant(
1220
0
          static_cast<wasm_func_t *>(static_cast<wasm::Ref *>(v.of.ref))->inst);
1221
0
    } else {
1222
0
      return WasmEdge::RefVariant(
1223
0
          WasmEdge::ValType(WasmEdge::TypeCode::FuncRef));
1224
0
    }
1225
0
  default:
1226
0
    assumingUnreachable();
1227
0
  }
1228
0
}
1229
1230
// wasm::Val to WasmEdge::ValVariant conversion.
1231
0
WasmEdge::ValVariant conv_cppval_to_wasmedge(const wasm::Val &v) {
1232
  // Note: the conversion will not transfer the ownership of wasm::Ref.
1233
0
  switch (v.kind()) {
1234
0
  case wasm::ValKind::I32:
1235
0
    return v.i32();
1236
0
  case wasm::ValKind::I64:
1237
0
    return v.i64();
1238
0
  case wasm::ValKind::F32:
1239
0
    return v.f32();
1240
0
  case wasm::ValKind::F64:
1241
0
    return v.f64();
1242
0
  case wasm::ValKind::EXTERNREF:
1243
0
    return WasmEdge::RefVariant(v.ref());
1244
0
  case wasm::ValKind::FUNCREF: {
1245
    // C-API funcrefs always come from wasm_func_as_ref / wasm_table_get, so
1246
    // ref() is a wasm::Func — recover the wasm_func_t and store its inst.
1247
0
    if (v.ref()) {
1248
0
      auto *cfunc = static_cast<wasm_func_t *>(
1249
0
          static_cast<wasm::Func *>(static_cast<wasm::Extern *>(v.ref())));
1250
0
      return WasmEdge::RefVariant(cfunc->inst);
1251
0
    }
1252
0
    return WasmEdge::RefVariant(WasmEdge::ValType(WasmEdge::TypeCode::FuncRef));
1253
0
  }
1254
0
  default:
1255
0
    assumingUnreachable();
1256
0
  }
1257
0
}
1258
1259
// allocmgr destructor backward implementation.
1260
// Uses cached info/finalizer from ref_entry_t to avoid type-unsafe casts.
1261
0
wasm_allocmgr_t::~wasm_allocmgr_t() {
1262
0
  for (auto &&[ptr, entry] : entries) {
1263
0
    if (entry.finalizer) {
1264
0
      entry.finalizer(entry.info);
1265
0
    }
1266
0
    entry.destroyer(ptr);
1267
0
  }
1268
0
  entries.clear();
1269
0
}
1270
1271
} // namespace
1272
1273
// The following are the C API implementation.
1274
#ifdef __cplusplus
1275
extern "C" {
1276
#endif
1277
1278
// >>>>>>>> wasm_byte_vec_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1279
1280
0
WASM_DECLARE_VEC_SCALAR_IMPL(byte, byte_t)
Unexecuted instantiation: wasm_byte_vec_new_uninitialized
Unexecuted instantiation: wasm_byte_vec_new
1281
1282
// <<<<<<<< wasm_byte_vec_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1283
1284
// >>>>>>>> wasm_config_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1285
1286
WASM_DECLARE_OWN_IMPL(config, wasm::Config)
1287
1288
0
WASMEDGE_CAPI_EXPORT OWN wasm_config_t *wasm_config_new() {
1289
0
  return new (std::nothrow) wasm_config_t;
1290
0
}
1291
1292
// <<<<<<<< wasm_config_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1293
1294
// >>>>>>>> wasm_engine_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1295
1296
WASM_DECLARE_OWN_IMPL(engine, wasm::Engine)
1297
1298
0
WASMEDGE_CAPI_EXPORT OWN wasm_engine_t *wasm_engine_new() {
1299
0
  return new (std::nothrow) wasm_engine_t();
1300
0
}
1301
1302
WASMEDGE_CAPI_EXPORT OWN wasm_engine_t *
1303
0
wasm_engine_new_with_config(OWN wasm_config_t *conf) {
1304
0
  if (conf) {
1305
0
    return new (std::nothrow) wasm_engine_t(wasm::make_own<wasm::Config>(conf));
1306
0
  } else {
1307
0
    return wasm_engine_new();
1308
0
  }
1309
0
}
1310
1311
// <<<<<<<< wasm_engine_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1312
1313
// >>>>>>>> wasm_store_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1314
1315
WASM_DECLARE_OWN_IMPL(store, wasm::Store)
1316
1317
0
WASMEDGE_CAPI_EXPORT OWN wasm_store_t *wasm_store_new(wasm_engine_t *engine) {
1318
0
  return static_cast<wasm_store_t *>(wasm::Store::make(engine).release());
1319
0
}
1320
1321
// <<<<<<<< wasm_store_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1322
1323
// >>>>>>>> wasm_valtype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1324
1325
0
WASM_DECLARE_TYPE_IMPL(valtype, wasm::ValType)
Unexecuted instantiation: wasm_valtype_vec_new_uninitialized
Unexecuted instantiation: wasm_valtype_vec_new
Unexecuted instantiation: wasm_valtype_vec_copy
1326
0
1327
0
WASMEDGE_CAPI_EXPORT OWN wasm_valtype_t *wasm_valtype_new(wasm_valkind_t kind) {
1328
  // Return the pointer to the instances.
1329
  // When delete the `wasm_valtype_t`, the `destroy()` function will do nothing
1330
  // when the unique pointer releases the pointer.
1331
0
  switch (kind) {
1332
0
  case WASM_I32:
1333
0
    return &wasm_valtype_i32;
1334
0
  case WASM_I64:
1335
0
    return &wasm_valtype_i64;
1336
0
  case WASM_F32:
1337
0
    return &wasm_valtype_f32;
1338
0
  case WASM_F64:
1339
0
    return &wasm_valtype_f64;
1340
0
  case WASM_EXTERNREF:
1341
0
    return &wasm_valtype_externref;
1342
0
  case WASM_FUNCREF:
1343
0
    return &wasm_valtype_funcref;
1344
0
  default:
1345
0
    assumingUnreachable();
1346
0
  }
1347
0
}
1348
1349
WASM_DECLARE_C_GET_ATTR(valtype, wasm_valkind_t, kind, static, WASM_I32, , )
1350
1351
// <<<<<<<< wasm_valtype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1352
1353
// >>>>>>>> wasm_functype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1354
1355
0
WASM_DECLARE_TYPE_IMPL(functype, wasm::FuncType)
Unexecuted instantiation: wasm_functype_vec_new_uninitialized
Unexecuted instantiation: wasm_functype_vec_new
Unexecuted instantiation: wasm_functype_vec_copy
1356
0
1357
0
WASMEDGE_CAPI_EXPORT OWN wasm_functype_t *
1358
0
wasm_functype_new(OWN wasm_valtype_vec_t *params,
1359
0
                  OWN wasm_valtype_vec_t *results) {
1360
0
  if (params && results) {
1361
0
    return new (std::nothrow) wasm_functype_t(
1362
0
        wasm::ownvec<wasm::ValType>::adopt(
1363
0
            params->size,
1364
0
            reinterpret_cast<wasm::own<wasm::ValType> *>(params->data)),
1365
0
        wasm::ownvec<wasm::ValType>::adopt(
1366
0
            results->size,
1367
0
            reinterpret_cast<wasm::own<wasm::ValType> *>(results->data)));
1368
0
  }
1369
0
  return nullptr;
1370
0
}
1371
1372
WASM_DECLARE_C_GET_ATTR(functype, wasm_valtype_vec_t *, params, reinterpret,
1373
                        nullptr, &, const)
1374
WASM_DECLARE_C_GET_ATTR(functype, wasm_valtype_vec_t *, results, reinterpret,
1375
                        nullptr, &, const)
1376
1377
// <<<<<<<< wasm_functype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1378
1379
// >>>>>>>> wasm_globaltype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1380
1381
0
WASM_DECLARE_TYPE_IMPL(globaltype, wasm::GlobalType)
Unexecuted instantiation: wasm_globaltype_vec_new_uninitialized
Unexecuted instantiation: wasm_globaltype_vec_new
Unexecuted instantiation: wasm_globaltype_vec_copy
1382
0
1383
0
WASMEDGE_CAPI_EXPORT OWN wasm_globaltype_t *
1384
0
wasm_globaltype_new(OWN wasm_valtype_t *valtype, wasm_mutability_t mutability) {
1385
0
  if (valtype) {
1386
0
    return new (std::nothrow) wasm_globaltype_t(
1387
0
        wasm::make_own(valtype), static_cast<wasm::Mutability>(mutability));
1388
0
  }
1389
0
  return nullptr;
1390
0
}
1391
1392
WASM_DECLARE_C_GET_ATTR(globaltype, wasm_valtype_t *, content, static, nullptr,
1393
                        , const)
1394
WASM_DECLARE_C_GET_ATTR(globaltype, wasm_mutability_t, mutability, static,
1395
                        WASM_CONST, , )
1396
1397
// <<<<<<<< wasm_globaltype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1398
1399
// >>>>>>>> wasm_tabletype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1400
1401
0
WASM_DECLARE_TYPE_IMPL(tabletype, wasm::TableType)
Unexecuted instantiation: wasm_tabletype_vec_new_uninitialized
Unexecuted instantiation: wasm_tabletype_vec_new
Unexecuted instantiation: wasm_tabletype_vec_copy
1402
0
1403
0
WASMEDGE_CAPI_EXPORT OWN wasm_tabletype_t *
1404
0
wasm_tabletype_new(OWN wasm_valtype_t *valtype, const wasm_limits_t *limits) {
1405
0
  if (valtype && limits) {
1406
0
    return new (std::nothrow) wasm_tabletype_t(
1407
0
        wasm::make_own(valtype), wasm::Limits(limits->min, limits->max));
1408
0
  }
1409
0
  return nullptr;
1410
0
}
1411
1412
WASM_DECLARE_C_GET_ATTR(tabletype, wasm_valtype_t *, element, static, nullptr, ,
1413
                        const)
1414
WASM_DECLARE_C_GET_ATTR(tabletype, wasm_limits_t *, limits, reinterpret,
1415
                        nullptr, &, const)
1416
1417
// <<<<<<<< wasm_tabletype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1418
1419
// >>>>>>>> wasm_memorytype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1420
1421
0
WASM_DECLARE_TYPE_IMPL(memorytype, wasm::MemoryType)
Unexecuted instantiation: wasm_memorytype_vec_new_uninitialized
Unexecuted instantiation: wasm_memorytype_vec_new
Unexecuted instantiation: wasm_memorytype_vec_copy
1422
0
1423
0
WASMEDGE_CAPI_EXPORT OWN wasm_memorytype_t *
1424
0
wasm_memorytype_new(const wasm_limits_t *limits) {
1425
0
  if (limits) {
1426
0
    return new (std::nothrow)
1427
0
        wasm_memorytype_t(wasm::Limits(limits->min, limits->max));
1428
0
  }
1429
0
  return nullptr;
1430
0
}
1431
1432
WASM_DECLARE_C_GET_ATTR(memorytype, wasm_limits_t *, limits, reinterpret,
1433
                        nullptr, &, const)
1434
1435
// <<<<<<<< wasm_memorytype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1436
1437
// >>>>>>>> wasm_tagtype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1438
1439
0
WASM_DECLARE_TYPE_IMPL(tagtype, wasm::TagType)
Unexecuted instantiation: wasm_tagtype_vec_new_uninitialized
Unexecuted instantiation: wasm_tagtype_vec_new
Unexecuted instantiation: wasm_tagtype_vec_copy
1440
0
1441
0
WASMEDGE_CAPI_EXPORT OWN wasm_tagtype_t *
1442
0
wasm_tagtype_new(OWN wasm_functype_t *functype) {
1443
0
  if (functype) {
1444
0
    return new (std::nothrow) wasm_tagtype_t(wasm::make_own(functype));
1445
0
  }
1446
0
  return nullptr;
1447
0
}
1448
1449
WASM_DECLARE_C_GET_ATTR(tagtype, wasm_functype_t *, functype, static, nullptr, ,
1450
                        const)
1451
1452
// <<<<<<<< wasm_tagtype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1453
1454
// >>>>>>>> wasm_externtype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1455
1456
0
WASM_DECLARE_TYPE_IMPL(externtype, wasm::ExternType)
Unexecuted instantiation: wasm_externtype_vec_new_uninitialized
Unexecuted instantiation: wasm_externtype_vec_new
Unexecuted instantiation: wasm_externtype_vec_copy
1457
0
1458
0
WASM_DECLARE_C_GET_ATTR(externtype, wasm_externkind_t, kind, static,
1459
0
                        WASM_EXTERN_FUNC, , )
1460
0
1461
0
WASM_EXTERNTYPE_C_CONV(func, extern, type, Type, , )
1462
0
WASM_EXTERNTYPE_C_CONV(func, extern, type, Type, _, const)
1463
0
WASM_EXTERNTYPE_C_CONV(global, extern, type, Type, , )
1464
0
WASM_EXTERNTYPE_C_CONV(global, extern, type, Type, _, const)
1465
0
WASM_EXTERNTYPE_C_CONV(table, extern, type, Type, , )
1466
0
WASM_EXTERNTYPE_C_CONV(table, extern, type, Type, _, const)
1467
0
WASM_EXTERNTYPE_C_CONV(memory, extern, type, Type, , )
1468
0
WASM_EXTERNTYPE_C_CONV(memory, extern, type, Type, _, const)
1469
0
WASM_EXTERNTYPE_C_CONV(tag, extern, type, Type, , )
1470
0
WASM_EXTERNTYPE_C_CONV(tag, extern, type, Type, _, const)
1471
0
WASM_EXTERNTYPE_C_CONV(extern, func, type, Type, , )
1472
0
WASM_EXTERNTYPE_C_CONV(extern, func, type, Type, _, const)
1473
0
WASM_EXTERNTYPE_C_CONV(extern, global, type, Type, , )
1474
0
WASM_EXTERNTYPE_C_CONV(extern, global, type, Type, _, const)
1475
0
WASM_EXTERNTYPE_C_CONV(extern, table, type, Type, , )
1476
0
WASM_EXTERNTYPE_C_CONV(extern, table, type, Type, _, const)
1477
0
WASM_EXTERNTYPE_C_CONV(extern, memory, type, Type, , )
1478
0
WASM_EXTERNTYPE_C_CONV(extern, memory, type, Type, _, const)
1479
0
WASM_EXTERNTYPE_C_CONV(extern, tag, type, Type, , )
1480
0
WASM_EXTERNTYPE_C_CONV(extern, tag, type, Type, _, const)
1481
0
1482
0
// <<<<<<<< wasm_externtype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1483
0
1484
0
// >>>>>>>> wasm_importtype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1485
0
1486
0
WASM_DECLARE_TYPE_IMPL(importtype, wasm::ImportType)
Unexecuted instantiation: wasm_importtype_vec_new_uninitialized
Unexecuted instantiation: wasm_importtype_vec_new
Unexecuted instantiation: wasm_importtype_vec_copy
1487
0
1488
0
WASMEDGE_CAPI_EXPORT OWN wasm_importtype_t *
1489
0
wasm_importtype_new(OWN wasm_name_t *module, OWN wasm_name_t *name,
1490
0
                    OWN wasm_externtype_t *externtype) {
1491
0
  if (module && name && externtype) {
1492
0
    return new (std::nothrow)
1493
0
        wasm_importtype_t(wasm::vec<byte_t>::adopt(module->size, module->data),
1494
0
                          wasm::vec<byte_t>::adopt(name->size, name->data),
1495
0
                          wasm::make_own(externtype));
1496
0
  }
1497
0
  return nullptr;
1498
0
}
1499
1500
WASM_DECLARE_C_GET_ATTR(importtype, wasm_name_t *, module, reinterpret,
1501
                        nullptr, &, const)
1502
WASM_DECLARE_C_GET_ATTR(importtype, wasm_name_t *, name, reinterpret,
1503
                        nullptr, &, const)
1504
WASM_DECLARE_C_GET_ATTR(importtype, wasm_externtype_t *, type, static, nullptr,
1505
                        , const)
1506
1507
// <<<<<<<< wasm_importtype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1508
1509
// >>>>>>>> wasm_exporttype_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1510
1511
0
WASM_DECLARE_TYPE_IMPL(exporttype, wasm::ExportType)
Unexecuted instantiation: wasm_exporttype_vec_new_uninitialized
Unexecuted instantiation: wasm_exporttype_vec_new
Unexecuted instantiation: wasm_exporttype_vec_copy
1512
0
1513
0
WASMEDGE_CAPI_EXPORT OWN wasm_exporttype_t *
1514
0
wasm_exporttype_new(OWN wasm_name_t *name, OWN wasm_externtype_t *externtype) {
1515
0
  if (name && externtype) {
1516
0
    return new (std::nothrow)
1517
0
        wasm_exporttype_t(wasm::vec<byte_t>::adopt(name->size, name->data),
1518
0
                          wasm::make_own(externtype));
1519
0
  }
1520
0
  return nullptr;
1521
0
}
1522
1523
WASM_DECLARE_C_GET_ATTR(exporttype, wasm_name_t *, name, reinterpret,
1524
                        nullptr, &, const)
1525
WASM_DECLARE_C_GET_ATTR(exporttype, wasm_externtype_t *, type, static, nullptr,
1526
                        , const)
1527
1528
// <<<<<<<< wasm_exporttype_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1529
1530
////////////////////////////////////////////////////////////////////////////////
1531
1532
// Runtime Objects
1533
1534
// >>>>>>>> wasm_val_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1535
1536
0
WASM_DECLARE_VEC_BASE_IMPL(val, wasm::Val, wasm::vec, wasm::vec, )
1537
1538
WASMEDGE_CAPI_EXPORT void wasm_val_vec_new(OWN wasm_val_vec_t *out, size_t size,
1539
0
                                           OWN wasm_val_t const data[]) {
1540
0
  if (out) {
1541
0
    *out = {0, nullptr};
1542
0
    if (size < UINT32_MAX) {
1543
0
      auto v = wasm::vec<wasm::Val>::make_uninitialized(size);
1544
0
      for (size_t i = 0; i < v.size(); ++i) {
1545
0
        v[i] = conv_val_to_cpp(data[i]);
1546
0
      }
1547
0
      *out = {v.size(), reinterpret_cast<wasm_val_t *>(v.release())};
1548
0
    }
1549
0
  }
1550
0
}
1551
1552
WASMEDGE_CAPI_EXPORT void wasm_val_vec_copy(OWN wasm_val_vec_t *out,
1553
0
                                            const wasm_val_vec_t *in) {
1554
0
  if (out) {
1555
0
    *out = {0, nullptr};
1556
0
  }
1557
0
  if (in && out && in->size < UINT32_MAX) {
1558
0
    auto v = wasm::vec<wasm::Val>::make_uninitialized(in->size);
1559
0
    for (size_t i = 0; i < v.size(); ++i) {
1560
0
      wasm_val_t val;
1561
0
      wasm_val_copy(&in->data[i], &val);
1562
0
      v[i] = conv_val_to_cpp(val);
1563
0
    }
1564
0
    *out = {v.size(), reinterpret_cast<wasm_val_t *>(v.release())};
1565
0
  }
1566
0
}
1567
1568
0
WASMEDGE_CAPI_EXPORT void wasm_val_delete(OWN wasm_val_t *v) {
1569
0
  if (v && is_ref(static_cast<wasm::ValKind>(v->kind))) {
1570
0
    wasm::make_own(v->of.ref);
1571
0
  }
1572
0
}
1573
1574
WASMEDGE_CAPI_EXPORT void wasm_val_copy(OWN wasm_val_t *out,
1575
0
                                        const wasm_val_t *in) {
1576
0
  if (out) {
1577
0
    if (in) {
1578
0
      *out = *in;
1579
0
      if (wasm::is_ref(static_cast<wasm::ValKind>(in->kind)) && in->of.ref) {
1580
0
        out->of.ref = static_cast<wasm_ref_t *>(in->of.ref->copy().release());
1581
0
      }
1582
0
    } else {
1583
0
      out->kind = WASM_I32;
1584
0
      out->of.i64 = 0;
1585
0
    }
1586
0
  }
1587
0
}
1588
1589
// <<<<<<<< wasm_val_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1590
1591
// >>>>>>>> wasm_ref_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1592
1593
WASM_DECLARE_REF_BASE_IMPL(ref, wasm::Ref)
1594
1595
// <<<<<<<< wasm_ref_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1596
1597
// >>>>>>>> wasm_frame_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1598
1599
WASM_DECLARE_OWN_IMPL(frame, wasm::Frame)
1600
0
WASM_DECLARE_VEC_PTR_IMPL(frame, wasm::Frame)
Unexecuted instantiation: wasm_frame_vec_new_uninitialized
Unexecuted instantiation: wasm_frame_vec_new
Unexecuted instantiation: wasm_frame_vec_copy
1601
1602
WASMEDGE_CAPI_EXPORT OWN wasm_frame_t *
1603
0
wasm_frame_copy(const wasm_frame_t *frame) {
1604
0
  return static_cast<wasm_frame_t *>(frame->copy().release());
1605
0
}
1606
1607
WASM_DECLARE_C_GET_ATTR(frame, wasm_instance_t *, instance, static, nullptr, , )
1608
WASM_DECLARE_C_GET_ATTR(frame, uint32_t, func_index, static, 0, , )
1609
WASM_DECLARE_C_GET_ATTR(frame, size_t, func_offset, static, 0, , )
1610
WASM_DECLARE_C_GET_ATTR(frame, size_t, module_offset, static, 0, , )
1611
1612
// <<<<<<<< wasm_frame_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1613
1614
// >>>>>>>> wasm_trap_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1615
1616
WASM_DECLARE_REF_IMPL(trap, wasm::Trap)
1617
1618
WASMEDGE_CAPI_EXPORT OWN wasm_trap_t *
1619
0
wasm_trap_new(wasm_store_t *store, const wasm_message_t *message) {
1620
0
  if (store && message) {
1621
0
    wasm_byte_vec_t v;
1622
0
    wasm_byte_vec_copy(&v, message);
1623
0
    return new (std::nothrow)
1624
0
        wasm_trap_t(store, wasm::vec<byte_t>::adopt(v.size, v.data));
1625
0
  }
1626
0
  return nullptr;
1627
0
}
1628
1629
WASMEDGE_CAPI_EXPORT void wasm_trap_message(const wasm_trap_t *trap,
1630
0
                                            OWN wasm_message_t *out) {
1631
0
  if (out) {
1632
0
    *out = {0, nullptr};
1633
0
    if (trap) {
1634
0
      auto v = trap->message();
1635
0
      *out = {v.size(), reinterpret_cast<wasm_byte_t *>(v.release())};
1636
0
    }
1637
0
  }
1638
0
}
1639
1640
WASMEDGE_CAPI_EXPORT OWN wasm_frame_t *
1641
0
wasm_trap_origin(const wasm_trap_t *trap) {
1642
0
  if (trap) {
1643
0
    return static_cast<wasm_frame_t *>(trap->origin().release());
1644
0
  }
1645
0
  return nullptr;
1646
0
}
1647
1648
WASMEDGE_CAPI_EXPORT void wasm_trap_trace(const wasm_trap_t *trap,
1649
0
                                          OWN wasm_frame_vec_t *out) {
1650
0
  if (out) {
1651
0
    *out = {0, nullptr};
1652
0
    if (trap) {
1653
0
      auto v = trap->trace();
1654
0
      *out = {v.size(), reinterpret_cast<wasm_frame_t **>(v.release())};
1655
0
    }
1656
0
  }
1657
0
}
1658
1659
// <<<<<<<< wasm_trap_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1660
1661
// >>>>>>>> wasm_foreign_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1662
1663
WASM_DECLARE_REF_IMPL(foreign, wasm::Foreign)
1664
1665
0
WASMEDGE_CAPI_EXPORT OWN wasm_foreign_t *wasm_foreign_new(wasm_store_t *store) {
1666
0
  return static_cast<wasm_foreign_t *>(wasm::Foreign::make(store).release());
1667
0
}
1668
1669
// <<<<<<<< wasm_foreign_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1670
1671
// >>>>>>>> wasm_module_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1672
1673
WASM_DECLARE_SHARABLE_REF_IMPL(module, wasm::Module)
1674
1675
WASMEDGE_CAPI_EXPORT OWN wasm_module_t *
1676
0
wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary) {
1677
0
  if (store && binary) {
1678
0
    wasm_byte_vec_t v;
1679
0
    wasm_byte_vec_copy(&v, binary);
1680
0
    auto mod = store->load.parseModule(WasmEdge::Span<const uint8_t>(
1681
0
        reinterpret_cast<const uint8_t *>(v.data), v.size));
1682
0
    if (mod && store->valid.validate(*mod->get())) {
1683
0
      return new (std::nothrow) wasm_module_t(
1684
0
          store, std::move(*mod), wasm::vec<byte_t>::adopt(v.size, v.data));
1685
0
    }
1686
0
    wasm_byte_vec_delete(&v);
1687
0
  }
1688
0
  return nullptr;
1689
0
}
1690
1691
WASMEDGE_CAPI_EXPORT bool wasm_module_validate(wasm_store_t *store,
1692
0
                                               const wasm_byte_vec_t *binary) {
1693
0
  if (store && binary) {
1694
0
    auto mod = store->load.parseModule(WasmEdge::Span<const uint8_t>(
1695
0
        reinterpret_cast<const uint8_t *>(binary->data), binary->size));
1696
0
    if (!mod) {
1697
0
      return false;
1698
0
    }
1699
0
    auto valid = store->valid.validate(*mod->get());
1700
0
    if (valid) {
1701
0
      return true;
1702
0
    }
1703
0
  }
1704
0
  return false;
1705
0
}
1706
1707
WASMEDGE_CAPI_EXPORT void wasm_module_imports(const wasm_module_t *module,
1708
0
                                              OWN wasm_importtype_vec_t *out) {
1709
0
  if (out) {
1710
0
    *out = {0, nullptr};
1711
0
    if (module) {
1712
0
      auto v = module->imports();
1713
0
      *out = {v.size(), reinterpret_cast<wasm_importtype_t **>(v.release())};
1714
0
    }
1715
0
  }
1716
0
}
1717
1718
WASMEDGE_CAPI_EXPORT void wasm_module_exports(const wasm_module_t *module,
1719
0
                                              OWN wasm_exporttype_vec_t *out) {
1720
0
  if (out) {
1721
0
    *out = {0, nullptr};
1722
0
    if (module) {
1723
0
      auto v = module->exports();
1724
0
      *out = {v.size(), reinterpret_cast<wasm_exporttype_t **>(v.release())};
1725
0
    }
1726
0
  }
1727
0
}
1728
1729
WASMEDGE_CAPI_EXPORT void wasm_module_serialize(const wasm_module_t *module,
1730
0
                                                OWN wasm_byte_vec_t *out) {
1731
0
  if (out) {
1732
0
    *out = {0, nullptr};
1733
0
    if (module) {
1734
0
      auto v = module->serialize();
1735
0
      *out = {v.size(), reinterpret_cast<wasm_byte_t *>(v.release())};
1736
0
    }
1737
0
  }
1738
0
}
1739
1740
WASMEDGE_CAPI_EXPORT OWN wasm_module_t *
1741
0
wasm_module_deserialize(wasm_store_t *store, const wasm_byte_vec_t *binary) {
1742
0
  return wasm_module_new(store, binary);
1743
0
}
1744
1745
WASMEDGE_CAPI_EXPORT OWN wasm_shared_module_t *
1746
0
wasm_module_share(const wasm_module_t *module) {
1747
0
  if (module) {
1748
0
    return static_cast<wasm_shared_module_t *>(module->share().release());
1749
0
  }
1750
0
  return nullptr;
1751
0
}
1752
1753
WASMEDGE_CAPI_EXPORT OWN wasm_module_t *
1754
0
wasm_module_obtain(wasm_store_t *store, const wasm_shared_module_t *shared) {
1755
0
  if (store && shared) {
1756
0
    return static_cast<wasm_module_t *>(
1757
0
        wasm::Module::obtain(store, shared).release());
1758
0
  }
1759
0
  return nullptr;
1760
0
}
1761
1762
// <<<<<<<< wasm_module_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1763
1764
// >>>>>>>> wasm_func_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1765
1766
WASM_DECLARE_REF_IMPL(func, wasm::Func)
1767
1768
WASMEDGE_CAPI_EXPORT OWN wasm_func_t *
1769
wasm_func_new(wasm_store_t *store, const wasm_functype_t *type,
1770
0
              wasm_func_callback_t callback) {
1771
0
  if (store && type && callback) {
1772
0
    return new (std::nothrow) wasm_func_t(store, *type, callback);
1773
0
  }
1774
0
  return nullptr;
1775
0
}
1776
1777
WASMEDGE_CAPI_EXPORT OWN wasm_func_t *
1778
wasm_func_new_with_env(wasm_store_t *store, const wasm_functype_t *type,
1779
                       wasm_func_callback_with_env_t callback, void *env,
1780
0
                       void (*finalizer)(void *)) {
1781
0
  if (store && type && callback) {
1782
0
    return new (std::nothrow)
1783
0
        wasm_func_t(store, *type, callback, env, finalizer);
1784
0
  }
1785
0
  return nullptr;
1786
0
}
1787
1788
WASMEDGE_CAPI_EXPORT OWN wasm_functype_t *
1789
0
wasm_func_type(const wasm_func_t *func) {
1790
0
  if (func) {
1791
0
    return static_cast<wasm_functype_t *>(func->type().release());
1792
0
  }
1793
0
  return nullptr;
1794
0
}
1795
1796
WASM_DECLARE_C_GET_ATTR(func, size_t, param_arity, static, 0, , )
1797
WASM_DECLARE_C_GET_ATTR(func, size_t, result_arity, static, 0, , )
1798
1799
WASMEDGE_CAPI_EXPORT OWN wasm_trap_t *wasm_func_call(const wasm_func_t *func,
1800
                                                     const wasm_val_vec_t *args,
1801
0
                                                     wasm_val_vec_t *results) {
1802
0
  if (!func || !func->inst) {
1803
0
    return nullptr;
1804
0
  }
1805
0
  const auto &ftype = func->inst->getFuncType();
1806
0
  const auto &ptypes = ftype.getParamTypes();
1807
0
  const auto &rtypes = ftype.getReturnTypes();
1808
1809
0
  std::vector<WasmEdge::ValVariant> params(ptypes.size());
1810
0
  if (args) {
1811
0
    for (size_t i = 0; i < ptypes.size() && i < args->size; ++i) {
1812
0
      params[i] = conv_cval_to_wasmedge(args->data[i]);
1813
0
    }
1814
0
  }
1815
1816
0
  auto res = func->store->engine->exec.invoke(func->inst, params, ptypes);
1817
0
  if (!res) {
1818
0
    return static_cast<wasm_trap_t *>(
1819
0
        buildTrap(func->store, res.error(), lookupFuncIdx(func->inst))
1820
0
            .release());
1821
0
  }
1822
0
  if (results) {
1823
0
    for (size_t i = 0; i < rtypes.size() && i < results->size; ++i) {
1824
0
      results->data[i] = conv_cval_from_wasmedge((*res)[i].first, rtypes[i]);
1825
      // Results from wasm_func_call are owning per the wasm-c-api spec:
1826
      // the caller is expected to wasm_val_delete (or wasm_ref_delete the
1827
      // payload). conv_cval_from_wasmedge returns a borrowed pointer, so
1828
      // increment the refcount here to transfer ownership.
1829
0
      if (results->data[i].of.ref &&
1830
0
          wasm::is_ref(static_cast<wasm::ValKind>(results->data[i].kind))) {
1831
0
        results->data[i].of.ref->copy_ref().release();
1832
0
      }
1833
0
    }
1834
0
  }
1835
0
  return nullptr;
1836
0
}
1837
1838
// <<<<<<<< wasm_func_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1839
1840
// >>>>>>>> wasm_global_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1841
1842
WASM_DECLARE_REF_IMPL(global, wasm::Global)
1843
1844
WASMEDGE_CAPI_EXPORT OWN wasm_global_t *
1845
wasm_global_new(wasm_store_t *store, const wasm_globaltype_t *type,
1846
0
                const wasm_val_t *val) {
1847
0
  if (store && type && val) {
1848
0
    return static_cast<wasm_global_t *>(
1849
0
        wasm::Global::make(store, type, conv_val_to_cpp(*val)).release());
1850
0
  }
1851
0
  return nullptr;
1852
0
}
1853
1854
WASMEDGE_CAPI_EXPORT OWN wasm_globaltype_t *
1855
0
wasm_global_type(const wasm_global_t *global) {
1856
0
  if (global) {
1857
0
    return static_cast<wasm_globaltype_t *>(global->type().release());
1858
0
  }
1859
0
  return nullptr;
1860
0
}
1861
1862
WASMEDGE_CAPI_EXPORT void wasm_global_get(const wasm_global_t *global,
1863
0
                                          OWN wasm_val_t *out) {
1864
0
  if (global && out) {
1865
0
    auto val = global->get();
1866
0
    *out = conv_val_to_c(val);
1867
    // global_get returns an owning wasm_val_t (caller will wasm_val_delete).
1868
    // conv_val_to_c only exposes a borrowed pointer; bump the refcount while
1869
    // val still owns the ref so the net is +1 transferred to the caller.
1870
0
    if (out->of.ref && wasm::is_ref(static_cast<wasm::ValKind>(out->kind))) {
1871
0
      out->of.ref->copy_ref().release();
1872
0
    }
1873
0
  }
1874
0
}
1875
1876
WASMEDGE_CAPI_EXPORT void wasm_global_set(wasm_global_t *global,
1877
0
                                          const wasm_val_t *val) {
1878
0
  if (global && val) {
1879
0
    global->set(conv_val_to_cpp(*val));
1880
0
  }
1881
0
}
1882
1883
// <<<<<<<< wasm_global_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1884
1885
// >>>>>>>> wasm_table_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1886
1887
WASM_DECLARE_REF_IMPL(table, wasm::Table)
1888
1889
WASMEDGE_CAPI_EXPORT OWN wasm_table_t *
1890
wasm_table_new(wasm_store_t *store, const wasm_tabletype_t *type,
1891
0
               wasm_ref_t *ref) {
1892
0
  return static_cast<wasm_table_t *>(
1893
0
      wasm::Table::make(store, type, ref).release());
1894
0
}
1895
1896
WASMEDGE_CAPI_EXPORT OWN wasm_tabletype_t *
1897
0
wasm_table_type(const wasm_table_t *table) {
1898
0
  if (table) {
1899
0
    return static_cast<wasm_tabletype_t *>(table->type().release());
1900
0
  }
1901
0
  return nullptr;
1902
0
}
1903
1904
WASMEDGE_CAPI_EXPORT OWN wasm_ref_t *wasm_table_get(const wasm_table_t *table,
1905
0
                                                    wasm_table_size_t index) {
1906
0
  if (table) {
1907
0
    return static_cast<wasm_ref_t *>(table->get(index).release());
1908
0
  }
1909
0
  return nullptr;
1910
0
}
1911
1912
WASMEDGE_CAPI_EXPORT bool
1913
0
wasm_table_set(wasm_table_t *table, wasm_table_size_t index, wasm_ref_t *ref) {
1914
0
  if (table) {
1915
0
    return table->set(index, ref);
1916
0
  }
1917
0
  return false;
1918
0
}
1919
1920
WASM_DECLARE_C_GET_ATTR(table, wasm_table_size_t, size, static, 0, , )
1921
1922
WASMEDGE_CAPI_EXPORT bool
1923
0
wasm_table_grow(wasm_table_t *table, wasm_table_size_t delta, wasm_ref_t *ref) {
1924
0
  if (table) {
1925
0
    return table->grow(delta, ref);
1926
0
  }
1927
0
  return false;
1928
0
}
1929
1930
// <<<<<<<< wasm_table_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1931
1932
// >>>>>>>> wasm_memory_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1933
1934
WASM_DECLARE_REF_IMPL(memory, wasm::Memory)
1935
1936
WASMEDGE_CAPI_EXPORT OWN wasm_memory_t *
1937
0
wasm_memory_new(wasm_store_t *store, const wasm_memorytype_t *type) {
1938
0
  return static_cast<wasm_memory_t *>(
1939
0
      wasm::Memory::make(store, type).release());
1940
0
}
1941
1942
WASMEDGE_CAPI_EXPORT OWN wasm_memorytype_t *
1943
0
wasm_memory_type(const wasm_memory_t *memory) {
1944
0
  if (memory) {
1945
0
    return static_cast<wasm_memorytype_t *>(memory->type().release());
1946
0
  }
1947
0
  return nullptr;
1948
0
}
1949
1950
0
WASMEDGE_CAPI_EXPORT byte_t *wasm_memory_data(wasm_memory_t *memory) {
1951
0
  if (memory) {
1952
0
    return static_cast<byte_t *>(memory->data());
1953
0
  }
1954
0
  return nullptr;
1955
0
}
1956
1957
WASM_DECLARE_C_GET_ATTR(memory, size_t, data_size, static, 0, , )
1958
WASM_DECLARE_C_GET_ATTR(memory, wasm_memory_pages_t, size, static, 0, , )
1959
1960
WASMEDGE_CAPI_EXPORT bool wasm_memory_grow(wasm_memory_t *memory,
1961
0
                                           wasm_memory_pages_t delta) {
1962
0
  if (memory) {
1963
0
    return memory->grow(static_cast<wasm::Memory::pages_t>(delta));
1964
0
  }
1965
0
  return false;
1966
0
}
1967
1968
// <<<<<<<< wasm_memory_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1969
1970
// >>>>>>>> wasm_extern_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1971
1972
WASM_DECLARE_REF_IMPL(extern, wasm::Extern)
1973
0
WASM_DECLARE_VEC_PTR_IMPL(extern, wasm::Extern)
Unexecuted instantiation: wasm_extern_vec_new_uninitialized
Unexecuted instantiation: wasm_extern_vec_new
Unexecuted instantiation: wasm_extern_vec_copy
1974
1975
WASM_DECLARE_C_GET_ATTR(extern, wasm_externkind_t, kind, static,
1976
                        WASM_EXTERN_FUNC, , )
1977
1978
WASMEDGE_CAPI_EXPORT OWN wasm_externtype_t *
1979
0
wasm_extern_type(const wasm_extern_t *external) {
1980
0
  return reinterpret_cast<wasm_externtype_t *>(external->type().release());
1981
0
}
1982
1983
WASM_EXTERNTYPE_C_CONV(func, extern, , , , )
1984
WASM_EXTERNTYPE_C_CONV(func, extern, , , _, const)
1985
WASM_EXTERNTYPE_C_CONV(global, extern, , , , )
1986
WASM_EXTERNTYPE_C_CONV(global, extern, , , _, const)
1987
WASM_EXTERNTYPE_C_CONV(table, extern, , , , )
1988
WASM_EXTERNTYPE_C_CONV(table, extern, , , _, const)
1989
WASM_EXTERNTYPE_C_CONV(memory, extern, , , , )
1990
WASM_EXTERNTYPE_C_CONV(memory, extern, , , _, const)
1991
WASM_EXTERNTYPE_C_CONV(extern, func, , , , )
1992
WASM_EXTERNTYPE_C_CONV(extern, func, , , _, const)
1993
WASM_EXTERNTYPE_C_CONV(extern, global, , , , )
1994
WASM_EXTERNTYPE_C_CONV(extern, global, , , _, const)
1995
WASM_EXTERNTYPE_C_CONV(extern, table, , , , )
1996
WASM_EXTERNTYPE_C_CONV(extern, table, , , _, const)
1997
WASM_EXTERNTYPE_C_CONV(extern, memory, , , , )
1998
WASM_EXTERNTYPE_C_CONV(extern, memory, , , _, const)
1999
2000
// <<<<<<<< wasm_extern_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2001
2002
// >>>>>>>> wasm_instance_t functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2003
2004
WASM_DECLARE_REF_IMPL(instance, wasm::Instance)
2005
2006
WASMEDGE_CAPI_EXPORT OWN wasm_instance_t *
2007
wasm_instance_new(wasm_store_t *store, const wasm_module_t *module,
2008
0
                  const wasm_extern_vec_t *imports, OWN wasm_trap_t **trap) {
2009
  // Copy the C imports vec into a wasm::vec view; the pointed-to externs are
2010
  // borrowed.
2011
0
  auto imports_vec = wasm::vec<wasm::Extern *>::make_uninitialized(
2012
0
      imports ? imports->size : 0);
2013
0
  if (imports) {
2014
0
    for (size_t i = 0; i < imports->size; ++i) {
2015
0
      imports_vec[i] = static_cast<wasm::Extern *>(imports->data[i]);
2016
0
    }
2017
0
  }
2018
0
  wasm::own<wasm::Trap> error;
2019
0
  auto *instance = static_cast<wasm_instance_t *>(
2020
0
      wasm::Instance::make(store, module, imports_vec, &error).release());
2021
0
  if (trap) {
2022
0
    *trap = static_cast<wasm_trap_t *>(error.release());
2023
0
  }
2024
0
  return instance;
2025
0
}
2026
2027
WASMEDGE_CAPI_EXPORT void wasm_instance_exports(const wasm_instance_t *instance,
2028
0
                                                OWN wasm_extern_vec_t *out) {
2029
0
  if (out) {
2030
0
    auto exports = instance->exports();
2031
0
    *out = {exports.size(),
2032
0
            reinterpret_cast<wasm_extern_t **>(exports.release())};
2033
0
  }
2034
0
}
2035
2036
// <<<<<<<< wasm_instance_t functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2037
2038
#ifdef OWN
2039
#undef OWN
2040
#endif
2041
2042
#ifdef __cplusplus
2043
} // extern "C"
2044
#endif
2045
2046
// The following are the C++ API implementation.
2047
2048
// >>>>>>>> wasm::Config functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2049
2050
0
wasm::own<wasm::Config> wasm::Config::make() {
2051
0
  return wasm::make_own(new (std::nothrow) wasm_config_t);
2052
0
}
2053
2054
0
void wasm::Config::destroy() { delete static_cast<wasm_config_t *>(this); }
2055
2056
// <<<<<<<< wasm::Config functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2057
2058
// >>>>>>>> wasm::Engine functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2059
2060
0
wasm::own<wasm::Engine> wasm::Engine::make(wasm::own<wasm::Config> &&config) {
2061
0
  if (config.get()) {
2062
0
    return wasm::make_own(new (std::nothrow) wasm_engine_t(std::move(config)));
2063
0
  }
2064
0
  return wasm::make_own(new (std::nothrow) wasm_engine_t());
2065
0
}
2066
2067
0
void wasm::Engine::destroy() { delete static_cast<wasm_engine_t *>(this); }
2068
2069
// <<<<<<<< wasm::Engine functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2070
2071
// >>>>>>>> wasm::Store functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2072
2073
0
wasm::own<wasm::Store> wasm::Store::make(wasm::Engine *engine) {
2074
0
  if (engine) {
2075
0
    return wasm::make_own(new (std::nothrow) wasm_store_t(engine));
2076
0
  }
2077
0
  return nullptr;
2078
0
}
2079
2080
0
void wasm::Store::destroy() { delete static_cast<wasm_store_t *>(this); }
2081
2082
// <<<<<<<< wasm::Store functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2083
2084
// >>>>>>>> wasm::ValType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2085
2086
0
void wasm::ValType::destroy() {
2087
  // Not to delete the struct because the ValTypes are global variables.
2088
0
}
2089
2090
0
wasm::own<wasm::ValType> wasm::ValType::make(wasm::ValKind kind) {
2091
0
  switch (kind) {
2092
0
  case ValKind::I32:
2093
0
    return own<ValType>(&wasm_valtype_i32);
2094
0
  case ValKind::I64:
2095
0
    return own<ValType>(&wasm_valtype_i64);
2096
0
  case ValKind::F32:
2097
0
    return own<ValType>(&wasm_valtype_f32);
2098
0
  case ValKind::F64:
2099
0
    return own<ValType>(&wasm_valtype_f64);
2100
0
  case ValKind::EXTERNREF:
2101
0
    return own<ValType>(&wasm_valtype_externref);
2102
0
  case ValKind::FUNCREF:
2103
0
    return own<ValType>(&wasm_valtype_funcref);
2104
0
  default:
2105
0
    assumingUnreachable();
2106
0
  }
2107
0
}
2108
2109
0
wasm::own<wasm::ValType> wasm::ValType::copy() const { return make(kind()); }
2110
2111
0
wasm::ValKind wasm::ValType::kind() const {
2112
0
  return (static_cast<const wasm_valtype_t *>(this))->mkind;
2113
0
}
2114
2115
// <<<<<<<< wasm::ValType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2116
2117
// >>>>>>>> wasm::FuncType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2118
2119
0
void wasm::FuncType::destroy() { delete static_cast<wasm_functype_t *>(this); }
2120
2121
wasm::own<wasm::FuncType>
2122
wasm::FuncType::make(wasm::ownvec<wasm::ValType> &&params,
2123
0
                     wasm::ownvec<wasm::ValType> &&results) {
2124
  // Check the inputs are valid.
2125
0
  if (params && results) {
2126
0
    return wasm::make_own(new (std::nothrow) wasm_functype_t(
2127
0
        std::move(params), std::move(results)));
2128
0
  }
2129
0
  return nullptr;
2130
0
}
2131
2132
0
wasm::own<wasm::FuncType> wasm::FuncType::copy() const {
2133
  // The `params` and `results` vectors here must be valid.
2134
0
  return make(params().deep_copy(), results().deep_copy());
2135
0
}
2136
2137
0
const wasm::ownvec<wasm::ValType> &wasm::FuncType::params() const {
2138
0
  return (static_cast<const wasm_functype_t *>(this))->mparams;
2139
0
}
2140
2141
0
const wasm::ownvec<wasm::ValType> &wasm::FuncType::results() const {
2142
0
  return (static_cast<const wasm_functype_t *>(this))->mresults;
2143
0
}
2144
2145
// <<<<<<<< wasm::FuncType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2146
2147
// >>>>>>>> wasm::GlobalType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2148
2149
0
void wasm::GlobalType::destroy() {
2150
0
  delete static_cast<wasm_globaltype_t *>(this);
2151
0
}
2152
2153
wasm::own<wasm::GlobalType>
2154
wasm::GlobalType::make(wasm::own<wasm::ValType> &&content,
2155
0
                       wasm::Mutability mutability) {
2156
0
  return wasm::make_own(new (std::nothrow)
2157
0
                            wasm_globaltype_t(std::move(content), mutability));
2158
0
}
2159
2160
0
wasm::own<wasm::GlobalType> wasm::GlobalType::copy() const {
2161
0
  return make(content()->copy(), mutability());
2162
0
}
2163
2164
0
const wasm::ValType *wasm::GlobalType::content() const {
2165
0
  return (static_cast<const wasm_globaltype_t *>(this))->mcontent.get();
2166
0
}
2167
2168
0
wasm::Mutability wasm::GlobalType::mutability() const {
2169
0
  return (static_cast<const wasm_globaltype_t *>(this))->mmutability;
2170
0
}
2171
2172
// <<<<<<<< wasm::GlobalType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2173
2174
// >>>>>>>> wasm::TableType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2175
2176
0
void wasm::TableType::destroy() {
2177
0
  delete static_cast<wasm_tabletype_t *>(this);
2178
0
}
2179
2180
wasm::own<wasm::TableType>
2181
0
wasm::TableType::make(wasm::own<wasm::ValType> &&element, wasm::Limits limits) {
2182
0
  return wasm::make_own(new (std::nothrow)
2183
0
                            wasm_tabletype_t(std::move(element), limits));
2184
0
}
2185
2186
0
wasm::own<wasm::TableType> wasm::TableType::copy() const {
2187
0
  return make(element()->copy(), limits());
2188
0
}
2189
2190
0
const wasm::ValType *wasm::TableType::element() const {
2191
0
  return (static_cast<const wasm_tabletype_t *>(this))->mvaltype.get();
2192
0
}
2193
2194
0
const wasm::Limits &wasm::TableType::limits() const {
2195
0
  return (static_cast<const wasm_tabletype_t *>(this))->mlimits;
2196
0
}
2197
2198
// <<<<<<<< wasm::TableType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2199
2200
// >>>>>>>> wasm::MemoryType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2201
2202
0
void wasm::MemoryType::destroy() {
2203
0
  delete static_cast<wasm_memorytype_t *>(this);
2204
0
}
2205
2206
0
wasm::own<wasm::MemoryType> wasm::MemoryType::make(wasm::Limits limits) {
2207
0
  return wasm::make_own(new (std::nothrow) wasm_memorytype_t(limits));
2208
0
}
2209
2210
0
wasm::own<wasm::MemoryType> wasm::MemoryType::copy() const {
2211
0
  return make(limits());
2212
0
}
2213
2214
0
const wasm::Limits &wasm::MemoryType::limits() const {
2215
0
  return (static_cast<const wasm_memorytype_t *>(this))->mlimits;
2216
0
}
2217
2218
// <<<<<<<< wasm::MemoryType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2219
2220
// >>>>>>>> wasm::TagType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2221
2222
0
void wasm::TagType::destroy() { delete static_cast<wasm_tagtype_t *>(this); }
2223
2224
0
wasm::own<wasm::TagType> wasm::TagType::make(wasm::own<wasm::FuncType> &&ft) {
2225
0
  if (!ft) {
2226
0
    return nullptr;
2227
0
  }
2228
0
  return wasm::make_own(new (std::nothrow) wasm_tagtype_t(std::move(ft)));
2229
0
}
2230
2231
0
wasm::own<wasm::TagType> wasm::TagType::copy() const {
2232
0
  auto *self = static_cast<const wasm_tagtype_t *>(this);
2233
0
  return make(self->mfunctype->copy());
2234
0
}
2235
2236
0
const wasm::FuncType *wasm::TagType::functype() const {
2237
0
  return static_cast<const wasm_tagtype_t *>(this)->mfunctype.get();
2238
0
}
2239
2240
// <<<<<<<< wasm::TagType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2241
2242
// >>>>>>>> wasm::ExternType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2243
2244
0
void wasm::ExternType::destroy() {
2245
0
  switch (kind()) {
2246
0
  case wasm::ExternKind::FUNC:
2247
0
    delete static_cast<wasm_functype_t *>(this);
2248
0
    break;
2249
0
  case wasm::ExternKind::GLOBAL:
2250
0
    delete static_cast<wasm_globaltype_t *>(this);
2251
0
    break;
2252
0
  case wasm::ExternKind::TABLE:
2253
0
    delete static_cast<wasm_tabletype_t *>(this);
2254
0
    break;
2255
0
  case wasm::ExternKind::MEMORY:
2256
0
    delete static_cast<wasm_memorytype_t *>(this);
2257
0
    break;
2258
0
  case wasm::ExternKind::TAG:
2259
0
    delete static_cast<wasm_tagtype_t *>(this);
2260
0
    break;
2261
0
  default:
2262
0
    assumingUnreachable();
2263
0
  }
2264
0
}
2265
2266
0
wasm::own<wasm::ExternType> wasm::ExternType::copy() const {
2267
0
  switch (kind()) {
2268
0
  case wasm::ExternKind::FUNC:
2269
0
    return func()->copy();
2270
0
  case wasm::ExternKind::GLOBAL:
2271
0
    return global()->copy();
2272
0
  case wasm::ExternKind::TABLE:
2273
0
    return table()->copy();
2274
0
  case wasm::ExternKind::MEMORY:
2275
0
    return memory()->copy();
2276
0
  case wasm::ExternKind::TAG:
2277
0
    return tag()->copy();
2278
0
  default:
2279
0
    assumingUnreachable();
2280
0
  }
2281
0
}
2282
2283
0
wasm::ExternKind wasm::ExternType::kind() const {
2284
0
  return static_cast<const wasm_externtype_t *>(this)->mkind;
2285
0
}
2286
2287
WASM_EXTERNTYPE_CPP_CONV(func, Func, Type, FUNC, )
2288
WASM_EXTERNTYPE_CPP_CONV(func, Func, Type, FUNC, const)
2289
WASM_EXTERNTYPE_CPP_CONV(global, Global, Type, GLOBAL, )
2290
WASM_EXTERNTYPE_CPP_CONV(global, Global, Type, GLOBAL, const)
2291
WASM_EXTERNTYPE_CPP_CONV(table, Table, Type, TABLE, )
2292
WASM_EXTERNTYPE_CPP_CONV(table, Table, Type, TABLE, const)
2293
WASM_EXTERNTYPE_CPP_CONV(memory, Memory, Type, MEMORY, )
2294
WASM_EXTERNTYPE_CPP_CONV(memory, Memory, Type, MEMORY, const)
2295
WASM_EXTERNTYPE_CPP_CONV(tag, Tag, Type, TAG, )
2296
WASM_EXTERNTYPE_CPP_CONV(tag, Tag, Type, TAG, const)
2297
2298
// <<<<<<<< wasm::ExternType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2299
2300
// >>>>>>>> wasm::ImportType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2301
2302
0
void wasm::ImportType::destroy() {
2303
0
  delete static_cast<wasm_importtype_t *>(this);
2304
0
}
2305
2306
wasm::own<wasm::ImportType>
2307
wasm::ImportType::make(wasm::Name &&module, wasm::Name &&name,
2308
0
                       wasm::own<wasm::ExternType> &&type) {
2309
0
  return wasm::make_own(new (std::nothrow) wasm_importtype_t(
2310
0
      std::move(module), std::move(name), std::move(type)));
2311
0
}
2312
2313
0
wasm::own<wasm::ImportType> wasm::ImportType::copy() const {
2314
0
  return make(module().copy(), name().copy(), type()->copy());
2315
0
}
2316
2317
0
const wasm::Name &wasm::ImportType::module() const {
2318
0
  return static_cast<const wasm_importtype_t *>(this)->mmodname;
2319
0
}
2320
2321
0
const wasm::Name &wasm::ImportType::name() const {
2322
0
  return static_cast<const wasm_importtype_t *>(this)->mname;
2323
0
}
2324
2325
0
const wasm::ExternType *wasm::ImportType::type() const {
2326
0
  return static_cast<const wasm_importtype_t *>(this)->mtype.get();
2327
0
}
2328
2329
// <<<<<<<< wasm::ImportType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2330
2331
// >>>>>>>> wasm::ExportType functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2332
2333
0
void wasm::ExportType::destroy() {
2334
0
  delete static_cast<wasm_exporttype_t *>(this);
2335
0
}
2336
2337
wasm::own<wasm::ExportType>
2338
0
wasm::ExportType::make(wasm::Name &&name, wasm::own<wasm::ExternType> &&type) {
2339
0
  return wasm::make_own(
2340
0
      new (std::nothrow) wasm_exporttype_t(std::move(name), std::move(type)));
2341
0
}
2342
2343
0
wasm::own<wasm::ExportType> wasm::ExportType::copy() const {
2344
0
  return make(name().copy(), type()->copy());
2345
0
}
2346
2347
0
const wasm::Name &wasm::ExportType::name() const {
2348
0
  return static_cast<const wasm_exporttype_t *>(this)->mname;
2349
0
}
2350
2351
0
const wasm::ExternType *wasm::ExportType::type() const {
2352
0
  return static_cast<const wasm_exporttype_t *>(this)->mtype.get();
2353
0
}
2354
2355
// <<<<<<<< wasm::ExportType functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2356
2357
////////////////////////////////////////////////////////////////////////////////
2358
2359
// Runtime Objects
2360
2361
// >>>>>>>> wasm::Val functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2362
2363
// The `wasm::Val` class has been fully implemented in header.
2364
2365
// <<<<<<<< wasm::Val functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2366
2367
// >>>>>>>> wasm::Ref functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2368
2369
0
void wasm::Ref::destroy() { static_cast<wasm_ref_t *>(this)->decrease_ref(); }
2370
2371
0
wasm::own<wasm::Ref> wasm::Ref::copy() const {
2372
0
  return static_cast<const wasm_ref_t *>(this)->copy_ref();
2373
0
}
2374
2375
0
bool wasm::Ref::same(const wasm::Ref *that) const {
2376
0
  return static_cast<const wasm_ref_t *>(this)->inner ==
2377
0
         static_cast<const wasm_ref_t *>(that)->inner;
2378
0
}
2379
2380
0
void *wasm::Ref::get_host_info() const {
2381
0
  return static_cast<const wasm_ref_t *>(this)->info;
2382
0
}
2383
2384
0
void wasm::Ref::set_host_info(void *info, void (*finalizer)(void *)) {
2385
0
  static_cast<wasm_ref_t *>(this)->info = info;
2386
0
  static_cast<wasm_ref_t *>(this)->finalizer = finalizer;
2387
0
}
2388
2389
// <<<<<<<< wasm::Ref functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2390
2391
// >>>>>>>> wasm::Frame functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2392
2393
0
void wasm::Frame::destroy() { delete static_cast<wasm_frame_t *>(this); }
2394
2395
0
wasm::own<wasm::Frame> wasm::Frame::copy() const {
2396
0
  return wasm::make_own(new (std::nothrow) wasm_frame_t(
2397
0
      *static_cast<const wasm_frame_t *>(this)));
2398
0
}
2399
2400
0
wasm::Instance *wasm::Frame::instance() const {
2401
  // TODO: Not supported yet.
2402
0
  return nullptr;
2403
0
}
2404
2405
0
uint32_t wasm::Frame::func_index() const {
2406
0
  return static_cast<const wasm_frame_t *>(this)->funcidx;
2407
0
}
2408
2409
0
size_t wasm::Frame::func_offset() const {
2410
  // Not implemented yet: stored field is always 0.
2411
0
  return static_cast<const wasm_frame_t *>(this)->funcoff;
2412
0
}
2413
2414
0
size_t wasm::Frame::module_offset() const {
2415
  // Not implemented yet: stored field is always 0.
2416
0
  return static_cast<const wasm_frame_t *>(this)->moduleoff;
2417
0
}
2418
2419
// <<<<<<<< wasm::Frame functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2420
2421
// >>>>>>>> wasm::Trap functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2422
2423
0
void wasm::Trap::destroy() { static_cast<wasm_trap_t *>(this)->decrease_ref(); }
2424
2425
wasm::own<wasm::Trap> wasm::Trap::make(wasm::Store *store,
2426
0
                                       const wasm::Message &msg) {
2427
0
  if (store) {
2428
0
    return wasm::make_own(new (std::nothrow) wasm_trap_t(store, msg.copy()));
2429
0
  }
2430
0
  return nullptr;
2431
0
}
2432
2433
0
wasm::own<wasm::Trap> wasm::Trap::copy() const {
2434
0
  return static_cast<const wasm_trap_t *>(this)->copy_ref();
2435
0
}
2436
2437
0
wasm::Message wasm::Trap::message() const {
2438
0
  return static_cast<const wasm_trap_t *>(this)->mmsg.copy();
2439
0
}
2440
2441
0
wasm::own<wasm::Frame> wasm::Trap::origin() const {
2442
0
  const auto &slot = static_cast<const wasm_trap_t *>(this)->morigin;
2443
0
  return wasm::make_own(new (std::nothrow) wasm_frame_t(slot));
2444
0
}
2445
2446
0
wasm::ownvec<wasm::Frame> wasm::Trap::trace() const {
2447
0
  const auto &slot = static_cast<const wasm_trap_t *>(this)->morigin;
2448
0
  auto v = wasm::ownvec<wasm::Frame>::make_uninitialized(1);
2449
0
  v[0] = wasm::make_own(new (std::nothrow) wasm_frame_t(slot));
2450
0
  return v;
2451
0
}
2452
2453
// <<<<<<<< wasm::Trap functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2454
2455
// >>>>>>>> wasm::Foreign functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2456
2457
0
void wasm::Foreign::destroy() {
2458
0
  static_cast<wasm_foreign_t *>(this)->decrease_ref();
2459
0
}
2460
2461
0
wasm::own<wasm::Foreign> wasm::Foreign::make(wasm::Store *store) {
2462
0
  if (store) {
2463
0
    return wasm::make_own(new (std::nothrow) wasm_foreign_t(store));
2464
0
  }
2465
0
  return nullptr;
2466
0
}
2467
2468
0
wasm::own<wasm::Foreign> wasm::Foreign::copy() const {
2469
0
  return static_cast<const wasm_foreign_t *>(this)->copy_ref();
2470
0
}
2471
2472
// <<<<<<<< wasm::Foreign functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2473
2474
// >>>>>>>> wasm::Modules functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2475
2476
0
void wasm::Module::destroy() {
2477
0
  static_cast<wasm_module_t *>(this)->decrease_ref();
2478
0
}
2479
2480
bool wasm::Module::validate(wasm::Store *store,
2481
0
                            const wasm::vec<byte_t> &binary) {
2482
0
  if (store) {
2483
0
    auto mod = static_cast<wasm_store_t *>(store)->load.parseModule(
2484
0
        WasmEdge::Span<const uint8_t>(
2485
0
            reinterpret_cast<const uint8_t *>(binary.get()), binary.size()));
2486
0
    if (!mod) {
2487
0
      return false;
2488
0
    }
2489
0
    auto valid =
2490
0
        static_cast<wasm_store_t *>(store)->valid.validate(*mod->get());
2491
0
    if (valid) {
2492
0
      return true;
2493
0
    }
2494
0
  }
2495
0
  return false;
2496
0
}
2497
2498
wasm::own<wasm::Module> wasm::Module::make(wasm::Store *store,
2499
0
                                           const wasm::vec<byte_t> &binary) {
2500
0
  if (store) {
2501
0
    auto *cstore = static_cast<wasm_store_t *>(store);
2502
0
    auto mod = cstore->load.parseModule(WasmEdge::Span<const uint8_t>(
2503
0
        reinterpret_cast<const uint8_t *>(binary.get()), binary.size()));
2504
0
    if (mod) {
2505
      // The executor requires a validated module before instantiation.
2506
0
      if (auto valid = cstore->valid.validate(*mod->get()); !valid) {
2507
0
        return nullptr;
2508
0
      }
2509
0
      return wasm::make_own(new (std::nothrow) wasm_module_t(
2510
0
          store, std::move(*mod), binary.copy()));
2511
0
    }
2512
0
  }
2513
0
  return nullptr;
2514
0
}
2515
2516
0
wasm::own<wasm::Module> wasm::Module::copy() const {
2517
0
  return static_cast<const wasm_module_t *>(this)->copy_ref();
2518
0
}
2519
2520
0
wasm::ownvec<wasm::ImportType> wasm::Module::imports() const {
2521
0
  const auto &importvec = static_cast<const wasm_module_t *>(this)
2522
0
                              ->ast->getImportSection()
2523
0
                              .getContent();
2524
  // The size of std::vector is not necessary to be checked.
2525
0
  auto v = wasm::ownvec<wasm::ImportType>::make_uninitialized(importvec.size());
2526
0
  for (size_t i = 0; i < v.size(); ++i) {
2527
0
    auto modname = wasm::Name::make(std::string(importvec[i].getModuleName()));
2528
0
    auto extname =
2529
0
        wasm::Name::make(std::string(importvec[i].getExternalName()));
2530
0
    wasm::own<wasm::ExternType> type;
2531
0
    switch (importvec[i].getExternalType()) {
2532
0
    case WasmEdge::ExternalType::Function: {
2533
0
      auto typeidx = importvec[i].getExternalFuncTypeIdx();
2534
0
      const auto &functype = static_cast<const wasm_module_t *>(this)
2535
0
                                 ->ast->getTypeSection()
2536
0
                                 .getContent()[typeidx]
2537
0
                                 .getCompositeType()
2538
0
                                 .getFuncType();
2539
0
      type = make_functype_from_wasmedge(functype);
2540
0
      break;
2541
0
    }
2542
0
    case WasmEdge::ExternalType::Table: {
2543
0
      type = make_tabletype_from_wasmedge(importvec[i].getExternalTableType());
2544
0
      break;
2545
0
    }
2546
0
    case WasmEdge::ExternalType::Memory: {
2547
0
      type =
2548
0
          make_memorytype_from_wasmedge(importvec[i].getExternalMemoryType());
2549
0
      break;
2550
0
    }
2551
0
    case WasmEdge::ExternalType::Global: {
2552
0
      type =
2553
0
          make_globaltype_from_wasmedge(importvec[i].getExternalGlobalType());
2554
0
      break;
2555
0
    }
2556
0
    case WasmEdge::ExternalType::Tag: {
2557
0
      type = make_tagtype_from_wasmedge(
2558
0
          importvec[i].getExternalTagType().getDefType());
2559
0
      break;
2560
0
    }
2561
0
    default:
2562
0
      assumingUnreachable();
2563
0
    }
2564
0
    v[i] = wasm::make_own(new (std::nothrow) wasm_importtype_t(
2565
0
        std::move(modname), std::move(extname), std::move(type)));
2566
0
  }
2567
0
  return v;
2568
0
}
2569
2570
0
wasm::ownvec<wasm::ExportType> wasm::Module::exports() const {
2571
  // Accumulate the imported instances.
2572
0
  const auto &importvec = static_cast<const wasm_module_t *>(this)
2573
0
                              ->ast->getImportSection()
2574
0
                              .getContent();
2575
0
  size_t impfunc = 0;
2576
0
  size_t imptable = 0;
2577
0
  size_t impmemory = 0;
2578
0
  size_t impglobal = 0;
2579
0
  size_t imptag = 0;
2580
0
  for (size_t i = 0; i < importvec.size(); ++i) {
2581
0
    switch (importvec[i].getExternalType()) {
2582
0
    case WasmEdge::ExternalType::Function:
2583
0
      ++impfunc;
2584
0
      break;
2585
0
    case WasmEdge::ExternalType::Table:
2586
0
      ++imptable;
2587
0
      break;
2588
0
    case WasmEdge::ExternalType::Memory:
2589
0
      ++impmemory;
2590
0
      break;
2591
0
    case WasmEdge::ExternalType::Global:
2592
0
      ++impglobal;
2593
0
      break;
2594
0
    case WasmEdge::ExternalType::Tag:
2595
0
      ++imptag;
2596
0
      break;
2597
0
    default:
2598
0
      assumingUnreachable();
2599
0
    }
2600
0
  }
2601
2602
0
  const auto &exportvec = static_cast<const wasm_module_t *>(this)
2603
0
                              ->ast->getExportSection()
2604
0
                              .getContent();
2605
  // The size of std::vector is not necessary to be checked.
2606
0
  auto v = wasm::ownvec<wasm::ExportType>::make_uninitialized(exportvec.size());
2607
0
  for (size_t i = 0; i < v.size(); ++i) {
2608
0
    auto extname =
2609
0
        wasm::Name::make(std::string(exportvec[i].getExternalName()));
2610
0
    auto extidx = exportvec[i].getExternalIndex();
2611
0
    wasm::own<wasm::ExternType> type;
2612
0
    switch (exportvec[i].getExternalType()) {
2613
      // The real index = external_index - import_num.
2614
0
    case WasmEdge::ExternalType::Function: {
2615
0
      auto typeidx = static_cast<const wasm_module_t *>(this)
2616
0
                         ->ast->getFunctionSection()
2617
0
                         .getContent()[extidx - impfunc];
2618
0
      const auto &functype = static_cast<const wasm_module_t *>(this)
2619
0
                                 ->ast->getTypeSection()
2620
0
                                 .getContent()[typeidx]
2621
0
                                 .getCompositeType()
2622
0
                                 .getFuncType();
2623
0
      type = make_functype_from_wasmedge(functype);
2624
0
      break;
2625
0
    }
2626
0
    case WasmEdge::ExternalType::Table: {
2627
0
      const auto &tabletype = static_cast<const wasm_module_t *>(this)
2628
0
                                  ->ast->getTableSection()
2629
0
                                  .getContent()[extidx - imptable]
2630
0
                                  .getTableType();
2631
0
      type = make_tabletype_from_wasmedge(tabletype);
2632
0
      break;
2633
0
    }
2634
0
    case WasmEdge::ExternalType::Memory: {
2635
0
      const auto &memorytype = static_cast<const wasm_module_t *>(this)
2636
0
                                   ->ast->getMemorySection()
2637
0
                                   .getContent()[extidx - impmemory];
2638
0
      type = make_memorytype_from_wasmedge(memorytype);
2639
0
      break;
2640
0
    }
2641
0
    case WasmEdge::ExternalType::Global: {
2642
0
      const auto &globaltype = static_cast<const wasm_module_t *>(this)
2643
0
                                   ->ast->getGlobalSection()
2644
0
                                   .getContent()[extidx - impglobal]
2645
0
                                   .getGlobalType();
2646
0
      type = make_globaltype_from_wasmedge(globaltype);
2647
0
      break;
2648
0
    }
2649
0
    case WasmEdge::ExternalType::Tag: {
2650
0
      const auto &tag = static_cast<const wasm_module_t *>(this)
2651
0
                            ->ast->getTagSection()
2652
0
                            .getContent()[extidx - imptag];
2653
0
      type = make_tagtype_from_wasmedge(tag.getDefType());
2654
0
      break;
2655
0
    }
2656
0
    default:
2657
0
      assumingUnreachable();
2658
0
    }
2659
0
    v[i] = wasm::make_own(new (std::nothrow) wasm_exporttype_t(
2660
0
        std::move(extname), std::move(type)));
2661
0
  }
2662
0
  return v;
2663
0
}
2664
2665
0
wasm::own<wasm::Shared<wasm::Module>> wasm::Module::share() const {
2666
0
  return wasm::make_own(new (std::nothrow) wasm_shared_module_t(
2667
0
      static_cast<const wasm_module_t *>(this)->binary.copy()));
2668
0
}
2669
2670
wasm::own<wasm::Module>
2671
wasm::Module::obtain(wasm::Store *store,
2672
0
                     const wasm::Shared<wasm::Module> *module) {
2673
0
  return wasm::Module::deserialize(
2674
0
      store, static_cast<const wasm_shared_module_t *>(module)->binary);
2675
0
}
2676
2677
0
wasm::vec<byte_t> wasm::Module::serialize() const {
2678
  // Re-emit the AST as canonical wasm binary via WasmEdge's Serializer. On
2679
  // failure (e.g. unsupported AST feature) fall back to the original binary
2680
  // so the wasm-c-api round-trip contract (serialize → deserialize → equiv
2681
  // module) still holds.
2682
0
  auto *self = static_cast<const wasm_module_t *>(this);
2683
0
  if (self->ast && self->store) {
2684
0
    if (auto bytes = self->store->load.serializeModule(*self->ast)) {
2685
0
      auto out = wasm::vec<byte_t>::make_uninitialized(bytes->size());
2686
0
      std::copy(bytes->begin(), bytes->end(), out.get());
2687
0
      return out;
2688
0
    }
2689
0
  }
2690
0
  return self->binary.copy();
2691
0
}
2692
2693
wasm::own<wasm::Module>
2694
wasm::Module::deserialize(wasm::Store *store,
2695
0
                          const wasm::vec<byte_t> &vec_byte) {
2696
  // The serialized form is canonical wasm binary; re-parse via the regular
2697
  // module-loading path.
2698
0
  return make(store, vec_byte);
2699
0
}
2700
2701
// <<<<<<<< wasm::Modules functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2702
2703
// >>>>>>>> wasm::Shared functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2704
2705
0
void wasm::Shared<wasm::Module>::destroy() {
2706
0
  delete static_cast<wasm_shared_module_t *>(this);
2707
0
}
2708
2709
// <<<<<<<< wasm::Shared functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2710
2711
// >>>>>>>> wasm::Func functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2712
2713
0
void wasm::Func::destroy() { static_cast<wasm_func_t *>(this)->decrease_ref(); }
2714
2715
wasm::own<wasm::Func> wasm::Func::make(wasm::Store *store,
2716
                                       const wasm::FuncType *type,
2717
0
                                       wasm::Func::callback callback) {
2718
0
  if (store && type && callback) {
2719
0
    return wasm::make_own(new (std::nothrow)
2720
0
                              wasm_func_t(store, *type, callback));
2721
0
  }
2722
0
  return nullptr;
2723
0
}
2724
2725
wasm::own<wasm::Func> wasm::Func::make(wasm::Store *store,
2726
                                       const wasm::FuncType *type,
2727
                                       wasm::Func::callback_with_env callback,
2728
0
                                       void *env, void (*finalizer)(void *)) {
2729
0
  if (store && type && callback) {
2730
0
    return wasm::make_own(
2731
0
        new (std::nothrow) wasm_func_t(store, *type, callback, env, finalizer));
2732
0
  }
2733
0
  return nullptr;
2734
0
}
2735
2736
0
wasm::own<wasm::Func> wasm::Func::copy() const {
2737
0
  return static_cast<const wasm_func_t *>(this)->copy_ref();
2738
0
}
2739
2740
0
wasm::own<wasm::FuncType> wasm::Func::type() const {
2741
0
  if (static_cast<const wasm_func_t *>(this)->inst) {
2742
0
    const auto &type =
2743
0
        static_cast<const wasm_func_t *>(this)->inst->getFuncType();
2744
0
    auto vp =
2745
0
        wasm::ownvec<ValType>::make_uninitialized(type.getParamTypes().size());
2746
0
    auto vr =
2747
0
        wasm::ownvec<ValType>::make_uninitialized(type.getReturnTypes().size());
2748
0
    for (size_t i = 0; i < type.getParamTypes().size(); ++i) {
2749
0
      vp[i] = wasm::ValType::make(
2750
0
          conv_valtype_from_wasmedge(type.getParamTypes()[i]));
2751
0
    }
2752
0
    for (size_t i = 0; i < type.getReturnTypes().size(); ++i) {
2753
0
      vr[i] = wasm::ValType::make(
2754
0
          conv_valtype_from_wasmedge(type.getReturnTypes()[i]));
2755
0
    }
2756
0
    return wasm::FuncType::make(std::move(vp), std::move(vr));
2757
0
  }
2758
0
  return wasm::FuncType::make();
2759
0
}
2760
2761
0
size_t wasm::Func::param_arity() const {
2762
0
  const auto *inst = static_cast<const wasm_func_t *>(this)->inst;
2763
0
  if (inst) {
2764
0
    return static_cast<size_t>(inst->getFuncType().getParamTypes().size());
2765
0
  }
2766
0
  return 0;
2767
0
}
2768
2769
0
size_t wasm::Func::result_arity() const {
2770
0
  const auto *inst = static_cast<const wasm_func_t *>(this)->inst;
2771
0
  if (inst) {
2772
0
    return static_cast<size_t>(inst->getFuncType().getReturnTypes().size());
2773
0
  }
2774
0
  return 0;
2775
0
}
2776
2777
wasm::own<wasm::Trap> wasm::Func::call(const wasm::vec<wasm::Val> &args,
2778
0
                                       wasm::vec<wasm::Val> &results) const {
2779
0
  auto *self = static_cast<const wasm_func_t *>(this);
2780
0
  if (!self->inst) {
2781
0
    return nullptr;
2782
0
  }
2783
0
  const auto &ftype = self->inst->getFuncType();
2784
0
  const auto &ptypes = ftype.getParamTypes();
2785
0
  const auto &rtypes = ftype.getReturnTypes();
2786
2787
0
  std::vector<WasmEdge::ValVariant> params(ptypes.size());
2788
0
  for (size_t i = 0; i < ptypes.size() && i < args.size(); ++i) {
2789
0
    params[i] = conv_cppval_to_wasmedge(args[i]);
2790
0
  }
2791
2792
0
  auto res = self->store->engine->exec.invoke(self->inst, params, ptypes);
2793
0
  if (!res) {
2794
0
    return buildTrap(self->store, res.error(), lookupFuncIdx(self->inst));
2795
0
  }
2796
0
  if (results.size() < rtypes.size()) {
2797
0
    results = wasm::vec<wasm::Val>::make_uninitialized(rtypes.size());
2798
0
  }
2799
0
  for (size_t i = 0; i < rtypes.size(); ++i) {
2800
0
    results[i] = conv_cppval_from_wasmedge((*res)[i].first, rtypes[i]);
2801
0
  }
2802
0
  return nullptr;
2803
0
}
2804
2805
// <<<<<<<< wasm::Func functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2806
2807
// >>>>>>>> wasm::Global functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2808
2809
0
void wasm::Global::destroy() {
2810
0
  static_cast<wasm_global_t *>(this)->decrease_ref();
2811
0
}
2812
2813
wasm::own<wasm::Global> wasm::Global::make(wasm::Store *store,
2814
                                           const wasm::GlobalType *type,
2815
0
                                           const wasm::Val &val) {
2816
0
  if (store && type) {
2817
0
    return wasm::make_own(new (std::nothrow) wasm_global_t(store, *type, val));
2818
0
  }
2819
0
  return nullptr;
2820
0
}
2821
2822
0
wasm::own<wasm::Global> wasm::Global::copy() const {
2823
0
  return static_cast<const wasm_global_t *>(this)->copy_ref();
2824
0
}
2825
2826
0
wasm::own<wasm::GlobalType> wasm::Global::type() const {
2827
0
  const auto &type =
2828
0
      static_cast<const wasm_global_t *>(this)->inst->getGlobalType();
2829
0
  return wasm::GlobalType::make(
2830
0
      wasm::ValType::make(conv_valtype_from_wasmedge(type.getValType())),
2831
0
      conv_valmut_from_wasmedge(type.getValMut()));
2832
0
}
2833
2834
0
wasm::Val wasm::Global::get() const {
2835
0
  auto *inst = static_cast<const wasm_global_t *>(this)->inst;
2836
0
  return conv_cppval_from_wasmedge(inst->getValue(),
2837
0
                                   inst->getGlobalType().getValType());
2838
0
}
2839
2840
0
void wasm::Global::set(const wasm::Val &val) {
2841
  // Replace the kept init value here. If the value type is a reference, this
2842
  // will help to keep the reference count.
2843
0
  auto *global = static_cast<wasm_global_t *>(this);
2844
0
  global->keepval = val.copy();
2845
0
  global->inst->getValue() = conv_cppval_to_wasmedge(val);
2846
0
}
2847
2848
// <<<<<<<< wasm::Global functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2849
2850
// >>>>>>>> wasm::Table functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2851
2852
0
void wasm::Table::destroy() {
2853
0
  static_cast<wasm_table_t *>(this)->decrease_ref();
2854
0
}
2855
2856
wasm::own<wasm::Table> wasm::Table::make(wasm::Store *store,
2857
                                         const wasm::TableType *type,
2858
0
                                         const wasm::Ref *init) {
2859
0
  if (store && type) {
2860
0
    return wasm::make_own(new (std::nothrow) wasm_table_t(store, *type, init));
2861
0
  }
2862
0
  return nullptr;
2863
0
}
2864
2865
0
wasm::own<wasm::Table> wasm::Table::copy() const {
2866
0
  return static_cast<const wasm_table_t *>(this)->copy_ref();
2867
0
}
2868
2869
0
wasm::own<wasm::TableType> wasm::Table::type() const {
2870
0
  const auto &type =
2871
0
      static_cast<const wasm_table_t *>(this)->inst->getTableType();
2872
0
  return wasm::TableType::make(
2873
0
      wasm::ValType::make(conv_reftype_from_wasmedge(type.getRefType())),
2874
0
      type.getLimit().hasMax()
2875
0
          ? wasm::Limits(static_cast<uint32_t>(type.getLimit().getMin()),
2876
0
                         static_cast<uint32_t>(type.getLimit().getMax()))
2877
0
          : wasm::Limits(static_cast<uint32_t>(type.getLimit().getMin())));
2878
0
}
2879
2880
0
wasm::own<wasm::Ref> wasm::Table::get(wasm::Table::size_t index) const {
2881
0
  auto *self = static_cast<const wasm_table_t *>(this);
2882
0
  auto *inst = self->inst;
2883
0
  if (auto res = inst->getRefAddr(static_cast<uint32_t>(index));
2884
0
      res && !(*res).isNull()) {
2885
0
    if (inst->getTableType().getRefType().isFuncRefType()) {
2886
      // Non-owning wrap; the FunctionInstance lives in the table's module.
2887
0
      auto *fi = (*res).getPtr<WasmEdge::Runtime::Instance::FunctionInstance>();
2888
0
      if (!fi) {
2889
0
        return nullptr;
2890
0
      }
2891
0
      auto *wf = new (std::nothrow) wasm_func_t(self->store, fi);
2892
0
      return wasm::own<wasm::Ref>(
2893
0
          static_cast<wasm::Ref *>(static_cast<wasm::Func *>(wf)));
2894
0
    } else {
2895
0
      auto *ref = (*res).getPtr<wasm_ref_t>();
2896
0
      return ref ? ref->copy_ref() : nullptr;
2897
0
    }
2898
0
  }
2899
0
  return nullptr;
2900
0
}
2901
2902
0
bool wasm::Table::set(wasm::Table::size_t index, const wasm::Ref *ref) {
2903
0
  auto *inst = static_cast<wasm_table_t *>(this)->inst;
2904
0
  if (inst->getTableType().getRefType().isExternRefType()) {
2905
    // For the externref of the element type, set the ref.
2906
0
    if (inst->setRefAddr(static_cast<uint32_t>(index),
2907
0
                         WasmEdge::RefVariant(const_cast<wasm::Ref *>(ref)))) {
2908
0
      return true;
2909
0
    }
2910
0
  } else {
2911
    // Funcref slot: ref was produced via wasm_func_as_ref, so we can recover
2912
    // the wasm_func_t through the wasm::Func subobject.
2913
0
    if (ref) {
2914
0
      auto *cfunc =
2915
0
          static_cast<const wasm_func_t *>(static_cast<const wasm::Func *>(
2916
0
              static_cast<const wasm::Extern *>(ref)));
2917
0
      if (cfunc->inst &&
2918
0
          inst->setRefAddr(index, WasmEdge::RefVariant(cfunc->inst))) {
2919
0
        return true;
2920
0
      }
2921
0
    } else {
2922
0
      if (inst->setRefAddr(index, WasmEdge::RefVariant(WasmEdge::ValType(
2923
0
                                      WasmEdge::TypeCode::FuncRef)))) {
2924
0
        return true;
2925
0
      }
2926
0
    }
2927
0
  }
2928
0
  return false;
2929
0
}
2930
2931
0
wasm::Table::size_t wasm::Table::size() const {
2932
0
  return static_cast<wasm::Table::size_t>(
2933
0
      static_cast<const wasm_table_t *>(this)->inst->getSize());
2934
0
}
2935
2936
0
bool wasm::Table::grow(wasm::Table::size_t delta, const wasm::Ref *ref) {
2937
0
  size_t orig = size();
2938
0
  if (static_cast<wasm_table_t *>(this)->inst->growTable(
2939
0
          static_cast<uint32_t>(delta))) {
2940
0
    for (size_t i = orig; i < orig + delta; ++i) {
2941
0
      set(i, ref);
2942
0
    }
2943
0
    return true;
2944
0
  } else {
2945
0
    return false;
2946
0
  }
2947
0
}
2948
2949
// <<<<<<<< wasm::Table functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2950
2951
// >>>>>>>> wasm::Memory functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2952
2953
0
void wasm::Memory::destroy() {
2954
0
  static_cast<wasm_memory_t *>(this)->decrease_ref();
2955
0
}
2956
2957
wasm::own<wasm::Memory> wasm::Memory::make(wasm::Store *store,
2958
0
                                           const wasm::MemoryType *type) {
2959
0
  if (store && type) {
2960
0
    return wasm::make_own(new (std::nothrow) wasm_memory_t(store, *type));
2961
0
  }
2962
0
  return nullptr;
2963
0
}
2964
2965
0
wasm::own<wasm::Memory> wasm::Memory::copy() const {
2966
0
  return static_cast<const wasm_memory_t *>(this)->copy_ref();
2967
0
}
2968
2969
0
wasm::own<wasm::MemoryType> wasm::Memory::type() const {
2970
0
  const auto &type =
2971
0
      static_cast<const wasm_memory_t *>(this)->inst->getMemoryType();
2972
0
  return wasm::MemoryType::make(
2973
0
      type.getLimit().hasMax()
2974
0
          ? wasm::Limits(static_cast<uint32_t>(type.getLimit().getMin()),
2975
0
                         static_cast<uint32_t>(type.getLimit().getMax()))
2976
0
          : wasm::Limits(static_cast<uint32_t>(type.getLimit().getMin())));
2977
0
}
2978
2979
0
byte_t *wasm::Memory::data() const {
2980
0
  return static_cast<const wasm_memory_t *>(this)->inst->getPointer<byte_t *>(
2981
0
      0);
2982
0
}
2983
2984
0
size_t wasm::Memory::data_size() const {
2985
0
  return static_cast<size_t>(
2986
0
      static_cast<const wasm_memory_t *>(this)->inst->getPageSize() *
2987
0
      wasm::Memory::page_size);
2988
0
}
2989
2990
0
wasm::Memory::pages_t wasm::Memory::size() const {
2991
0
  return static_cast<wasm::Memory::pages_t>(
2992
0
      static_cast<const wasm_memory_t *>(this)->inst->getPageSize());
2993
0
}
2994
2995
0
bool wasm::Memory::grow(wasm::Memory::pages_t delta) {
2996
0
  if (static_cast<wasm_memory_t *>(this)->inst->growPage(
2997
0
          static_cast<uint32_t>(delta))) {
2998
0
    return true;
2999
0
  } else {
3000
0
    return false;
3001
0
  }
3002
0
}
3003
3004
// <<<<<<<< wasm::Memory functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
3005
3006
// >>>>>>>> wasm::Extern functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
3007
3008
0
void wasm::Extern::destroy() {
3009
0
  static_cast<wasm_extern_t *>(this)->decrease_ref();
3010
0
}
3011
3012
0
wasm::own<wasm::Extern> wasm::Extern::copy() const {
3013
0
  return static_cast<const wasm_extern_t *>(this)->copy_ref();
3014
0
}
3015
3016
0
wasm::ExternKind wasm::Extern::kind() const {
3017
0
  return static_cast<const wasm_extern_t *>(this)->mkind;
3018
0
}
3019
3020
0
wasm::own<wasm::ExternType> wasm::Extern::type() const {
3021
0
  switch (kind()) {
3022
0
  case wasm::ExternKind::FUNC:
3023
0
    return func()->type();
3024
0
  case wasm::ExternKind::GLOBAL:
3025
0
    return global()->type();
3026
0
  case wasm::ExternKind::TABLE:
3027
0
    return table()->type();
3028
0
  case wasm::ExternKind::MEMORY:
3029
0
    return memory()->type();
3030
0
  default:
3031
0
    assumingUnreachable();
3032
0
  }
3033
0
}
3034
3035
WASM_EXTERNTYPE_CPP_CONV(func, Func, , FUNC, )
3036
WASM_EXTERNTYPE_CPP_CONV(func, Func, , FUNC, const)
3037
WASM_EXTERNTYPE_CPP_CONV(global, Global, , GLOBAL, )
3038
WASM_EXTERNTYPE_CPP_CONV(global, Global, , GLOBAL, const)
3039
WASM_EXTERNTYPE_CPP_CONV(table, Table, , TABLE, )
3040
WASM_EXTERNTYPE_CPP_CONV(table, Table, , TABLE, const)
3041
WASM_EXTERNTYPE_CPP_CONV(memory, Memory, , MEMORY, )
3042
WASM_EXTERNTYPE_CPP_CONV(memory, Memory, , MEMORY, const)
3043
3044
// <<<<<<<< wasm::Extern functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
3045
3046
// >>>>>>>> wasm::Instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
3047
3048
0
void wasm::Instance::destroy() {
3049
0
  static_cast<wasm_instance_t *>(this)->decrease_ref();
3050
0
}
3051
3052
wasm::own<wasm::Instance>
3053
wasm::Instance::make(wasm::Store *store, const wasm::Module *module,
3054
                     const wasm::vec<wasm::Extern *> &imports,
3055
0
                     own<wasm::Trap> *trap_out) {
3056
0
  if (trap_out) {
3057
0
    *trap_out = nullptr;
3058
0
  }
3059
0
  if (!store || !module) {
3060
0
    return nullptr;
3061
0
  }
3062
0
  auto *cstore = static_cast<wasm_store_t *>(store);
3063
0
  auto *cmodule = static_cast<const wasm_module_t *>(module);
3064
3065
  // The user's imports vec must align positionally with the module's import
3066
  // declarations; reject up front if the sizes don't match.
3067
0
  const auto &importsec = cmodule->ast->getImportSection().getContent();
3068
0
  if (imports.size() < importsec.size()) {
3069
0
    return nullptr;
3070
0
  }
3071
3072
  // One shim per distinct module-name (executor resolves by name).
3073
0
  std::unordered_map<std::string, std::unique_ptr<wasm_import_module_t>> modmap;
3074
  // Retain each host-provided import for the instance's lifetime; the import
3075
  // shim only borrows the underlying runtime instance pointer.
3076
0
  std::vector<wasm::own<wasm::Extern>> retainedImports;
3077
0
  retainedImports.reserve(importsec.size());
3078
0
  for (size_t i = 0; i < importsec.size(); ++i) {
3079
0
    auto *ext = imports[i];
3080
0
    if (!ext) {
3081
0
      return nullptr;
3082
0
    }
3083
0
    retainedImports.push_back(ext->copy());
3084
0
    auto modname = std::string(importsec[i].getModuleName());
3085
0
    auto name = std::string(importsec[i].getExternalName());
3086
0
    auto it = modmap.find(modname);
3087
0
    if (it == modmap.end()) {
3088
0
      it =
3089
0
          modmap
3090
0
              .emplace(modname, std::make_unique<wasm_import_module_t>(modname))
3091
0
              .first;
3092
0
    }
3093
0
    auto *modinst = it->second.get();
3094
0
    switch (ext->kind()) {
3095
0
    case wasm::ExternKind::FUNC: {
3096
0
      auto *cfunc = static_cast<wasm_func_t *>(ext->func());
3097
0
      if (!cfunc || !cfunc->inst) {
3098
0
        return nullptr;
3099
0
      }
3100
0
      modinst->aliasFunc(name, cfunc->inst);
3101
0
      break;
3102
0
    }
3103
0
    case wasm::ExternKind::GLOBAL: {
3104
0
      auto *cglob = static_cast<wasm_global_t *>(ext->global());
3105
0
      if (!cglob || !cglob->inst) {
3106
0
        return nullptr;
3107
0
      }
3108
0
      modinst->aliasGlobal(name, cglob->inst);
3109
0
      break;
3110
0
    }
3111
0
    case wasm::ExternKind::TABLE: {
3112
0
      auto *ctab = static_cast<wasm_table_t *>(ext->table());
3113
0
      if (!ctab || !ctab->inst) {
3114
0
        return nullptr;
3115
0
      }
3116
0
      modinst->aliasTable(name, ctab->inst);
3117
0
      break;
3118
0
    }
3119
0
    case wasm::ExternKind::MEMORY: {
3120
0
      auto *cmem = static_cast<wasm_memory_t *>(ext->memory());
3121
0
      if (!cmem || !cmem->inst) {
3122
0
        return nullptr;
3123
0
      }
3124
0
      modinst->aliasMemory(name, cmem->inst);
3125
0
      break;
3126
0
    }
3127
0
    default:
3128
0
      return nullptr;
3129
0
    }
3130
0
  }
3131
3132
  // Temporarily register each shim so instantiateModule can resolve imports
3133
  // by name; unregister all after to avoid collisions on later calls.
3134
0
  std::vector<std::unique_ptr<wasm_import_module_t>> importmods;
3135
0
  std::vector<std::string> registered;
3136
0
  for (auto &kv : modmap) {
3137
0
    if (auto reg =
3138
0
            cstore->engine->exec.registerModule(cstore->store, *(kv.second));
3139
0
        !reg) {
3140
0
      for (const auto &n : registered) {
3141
0
        cstore->store.unregisterModule(n);
3142
0
      }
3143
0
      return nullptr;
3144
0
    }
3145
0
    registered.push_back(kv.first);
3146
0
    importmods.push_back(std::move(kv.second));
3147
0
  }
3148
3149
  // Capture export order, since ModuleInstance's export maps are alphabetical.
3150
0
  std::vector<wasm_instance_t::export_entry_t> exportorder;
3151
0
  for (const auto &exp : cmodule->ast->getExportSection().getContent()) {
3152
0
    exportorder.push_back(
3153
0
        {std::string(exp.getExternalName()), exp.getExternalType()});
3154
0
  }
3155
3156
  // Instantiate, then unregister regardless of outcome.
3157
0
  auto res =
3158
0
      cstore->engine->exec.instantiateModule(cstore->store, *cmodule->ast);
3159
0
  for (const auto &n : registered) {
3160
0
    cstore->store.unregisterModule(n);
3161
0
  }
3162
0
  if (!res) {
3163
0
    if (trap_out) {
3164
0
      *trap_out =
3165
0
          buildTrap(store, res.error(),
3166
0
                    cmodule->ast->getStartSection().getContent().value_or(0));
3167
0
    }
3168
0
    return nullptr;
3169
0
  }
3170
3171
0
  return wasm::make_own(new (std::nothrow) wasm_instance_t(
3172
0
      store, std::move(*res), std::move(importmods), std::move(retainedImports),
3173
0
      std::move(exportorder)));
3174
0
}
3175
3176
0
wasm::own<wasm::Instance> wasm::Instance::copy() const {
3177
0
  return static_cast<const wasm_instance_t *>(this)->copy_ref();
3178
0
}
3179
3180
0
wasm::ownvec<wasm::Extern> wasm::Instance::exports() const {
3181
0
  auto *self = static_cast<const wasm_instance_t *>(this);
3182
0
  if (!self->modinst) {
3183
0
    return wasm::ownvec<wasm::Extern>::make();
3184
0
  }
3185
0
  auto v =
3186
0
      wasm::ownvec<wasm::Extern>::make_uninitialized(self->exportorder.size());
3187
0
  for (size_t i = 0; i < self->exportorder.size(); ++i) {
3188
0
    const auto &entry = self->exportorder[i];
3189
0
    switch (entry.kind) {
3190
0
    case WasmEdge::ExternalType::Function: {
3191
0
      auto *fi = self->modinst->findFuncExports(entry.name);
3192
0
      if (!fi) {
3193
0
        return wasm::ownvec<wasm::Extern>::make();
3194
0
      }
3195
0
      v[i] = wasm::own<wasm::Extern>(
3196
0
          static_cast<wasm::Extern *>(static_cast<wasm::Func *>(
3197
0
              new (std::nothrow) wasm_func_t(self->store, fi))));
3198
0
      break;
3199
0
    }
3200
0
    case WasmEdge::ExternalType::Global: {
3201
0
      auto *gi = self->modinst->findGlobalExports(entry.name);
3202
0
      if (!gi) {
3203
0
        return wasm::ownvec<wasm::Extern>::make();
3204
0
      }
3205
0
      v[i] = wasm::own<wasm::Extern>(
3206
0
          static_cast<wasm::Extern *>(static_cast<wasm::Global *>(
3207
0
              new (std::nothrow) wasm_global_t(self->store, gi))));
3208
0
      break;
3209
0
    }
3210
0
    case WasmEdge::ExternalType::Table: {
3211
0
      auto *ti = self->modinst->findTableExports(entry.name);
3212
0
      if (!ti) {
3213
0
        return wasm::ownvec<wasm::Extern>::make();
3214
0
      }
3215
0
      v[i] = wasm::own<wasm::Extern>(
3216
0
          static_cast<wasm::Extern *>(static_cast<wasm::Table *>(
3217
0
              new (std::nothrow) wasm_table_t(self->store, ti))));
3218
0
      break;
3219
0
    }
3220
0
    case WasmEdge::ExternalType::Memory: {
3221
0
      auto *mi = self->modinst->findMemoryExports(entry.name);
3222
0
      if (!mi) {
3223
0
        return wasm::ownvec<wasm::Extern>::make();
3224
0
      }
3225
0
      v[i] = wasm::own<wasm::Extern>(
3226
0
          static_cast<wasm::Extern *>(static_cast<wasm::Memory *>(
3227
0
              new (std::nothrow) wasm_memory_t(self->store, mi))));
3228
0
      break;
3229
0
    }
3230
0
    default:
3231
0
      return wasm::ownvec<wasm::Extern>::make();
3232
0
    }
3233
0
  }
3234
0
  return v;
3235
0
}
3236
3237
// <<<<<<<< wasm::Instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<