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