1 /**
2  * \file wasmtime/types/func.hh
3  */
4 
5 #ifndef WASMTIME_TYPES_FUNC_HH
6 #define WASMTIME_TYPES_FUNC_HH
7 
8 #include <wasmtime/types/val.hh>
9 
10 namespace wasmtime {
11 
12 /**
13  * \brief Type information for a WebAssembly function.
14  */
15 class FuncType {
16   friend class Func;
17   friend class Linker;
18   friend class TagType;
19 
20   struct deleter {
operator ()wasmtime::FuncType::deleter21     void operator()(wasm_functype_t *p) const { wasm_functype_delete(p); }
22   };
23 
24   std::unique_ptr<wasm_functype_t, deleter> ptr;
25 
26 public:
27   /// Non-owning reference to a `FuncType`, must not be used after the original
28   /// owner has been deleted.
29   class Ref {
30     friend class FuncType;
31     const wasm_functype_t *ptr;
32 
33   public:
34     /// Creates a new reference from the underlying C API representation.
Ref(const wasm_functype_t * ptr)35     Ref(const wasm_functype_t *ptr) : ptr(ptr) {}
36     /// Creates a new reference to the given type.
Ref(const FuncType & ty)37     Ref(const FuncType &ty) : Ref(ty.ptr.get()) {}
38 
39     /// Returns the list of types this function type takes as parameters.
params() const40     ValType::ListRef params() const { return wasm_functype_params(ptr); }
41 
42     /// Returns the list of types this function type returns.
results() const43     ValType::ListRef results() const { return wasm_functype_results(ptr); }
44   };
45 
46 private:
47   Ref ref;
FuncType(wasm_functype_t * ptr)48   FuncType(wasm_functype_t *ptr) : ptr(ptr), ref(ptr) {}
49 
50 public:
51   /// Creates a new function type from the given list of parameters and results.
FuncType(std::initializer_list<ValType> params,std::initializer_list<ValType> results)52   FuncType(std::initializer_list<ValType> params,
53            std::initializer_list<ValType> results)
54       : ref(nullptr) {
55     *this = FuncType::from_iters(params, results);
56   }
57 
58   /// Copies a reference into a uniquely owned function type.
FuncType(Ref other)59   FuncType(Ref other) : FuncType(wasm_functype_copy(other.ptr)) {}
60   /// Copies another type's information into this one.
FuncType(const FuncType & other)61   FuncType(const FuncType &other)
62       : FuncType(wasm_functype_copy(other.ptr.get())) {}
63   /// Copies another type's information into this one.
operator =(const FuncType & other)64   FuncType &operator=(const FuncType &other) {
65     ptr.reset(wasm_functype_copy(other.ptr.get()));
66     return *this;
67   }
68   ~FuncType() = default;
69   /// Moves type information from another type into this one.
70   FuncType(FuncType &&other) = default;
71   /// Moves type information from another type into this one.
72   FuncType &operator=(FuncType &&other) = default;
73 
74   /// Creates a new function type from the given list of parameters and results.
75   template <typename P, typename R>
from_iters(P params,R results)76   static FuncType from_iters(P params, R results) {
77     wasm_valtype_vec_t param_vec;
78     wasm_valtype_vec_t result_vec;
79     wasm_valtype_vec_new_uninitialized(&param_vec, params.size());
80     wasm_valtype_vec_new_uninitialized(&result_vec, results.size());
81     size_t i = 0;
82 
83     for (auto val : params) {
84       param_vec.data[i++] = val.ptr.release(); // NOLINT
85     }
86     i = 0;
87     for (auto val : results) {
88       result_vec.data[i++] = val.ptr.release(); // NOLINT
89     }
90 
91     return wasm_functype_new(&param_vec, &result_vec);
92   }
93 
94   /// \brief Returns the underlying `Ref`, a non-owning reference pointing to
95   /// this instance.
operator ->()96   Ref *operator->() { return &ref; }
97   /// \brief Returns the underlying `Ref`, a non-owning reference pointing to
98   /// this instance.
operator *()99   Ref *operator*() { return &ref; }
100 };
101 
102 }; // namespace wasmtime
103 
104 #endif // WASMTIME_TYPES_FUNC_HH
105