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