1 /**
2  * \file wasmtime/table.hh
3  */
4 
5 #ifndef WASMTIME_TABLE_HH
6 #define WASMTIME_TABLE_HH
7 
8 #include <optional>
9 
10 #include <wasmtime/error.hh>
11 #include <wasmtime/store.hh>
12 #include <wasmtime/table.h>
13 #include <wasmtime/types/table.hh>
14 #include <wasmtime/types/val.hh>
15 #include <wasmtime/val.hh>
16 
17 namespace wasmtime {
18 
19 /**
20  * \brief A WebAssembly table.
21  *
22  * This class represents a WebAssembly table, either created through
23  * instantiating a module or a host table. Tables are contiguous vectors of
24  * WebAssembly reference types, currently either `externref` or `funcref`.
25  *
26  * Note that this type does not itself own any resources. It points to resources
27  * owned within a `Store` and the `Store` must be passed in as the first
28  * argument to the functions defined on `Table`. Note that if the wrong `Store`
29  * is passed in then the process will be aborted.
30  */
31 class Table {
32   friend class Instance;
33   wasmtime_table_t table;
34 
35 public:
36   /// Creates a new table from the raw underlying C API representation.
Table(wasmtime_table_t table)37   Table(wasmtime_table_t table) : table(table) {}
38 
39   /**
40    * \brief Creates a new host-defined table.
41    *
42    * \param cx the store in which to create the table.
43    * \param ty the type of the table to be created
44    * \param init the initial value for all table slots.
45    *
46    * Returns an error if `init` has the wrong value for the `ty` specified.
47    */
create(Store::Context cx,const TableType & ty,const Val & init)48   static Result<Table> create(Store::Context cx, const TableType &ty,
49                               const Val &init) {
50     wasmtime_table_t table;
51     auto *error = wasmtime_table_new(cx.ptr, ty.ptr.get(), &init.val, &table);
52     if (error != nullptr) {
53       return Error(error);
54     }
55     return Table(table);
56   }
57 
58   /// Returns the type of this table.
type(Store::Context cx) const59   TableType type(Store::Context cx) const {
60     return wasmtime_table_type(cx.ptr, &table);
61   }
62 
63   /// Returns the size, in elements, that the table currently has.
size(Store::Context cx) const64   uint64_t size(Store::Context cx) const {
65     return wasmtime_table_size(cx.ptr, &table);
66   }
67 
68   /// Loads a value from the specified index in this table.
69   ///
70   /// Returns `std::nullopt` if `idx` is out of bounds.
get(Store::Context cx,uint64_t idx) const71   std::optional<Val> get(Store::Context cx, uint64_t idx) const {
72     Val val;
73     if (wasmtime_table_get(cx.ptr, &table, idx, &val.val)) {
74       return std::optional(std::move(val));
75     }
76     return std::nullopt;
77   }
78 
79   /// Stores a value into the specified index in this table.
80   ///
81   /// Returns an error if `idx` is out of bounds or if `val` has the wrong type.
set(Store::Context cx,uint64_t idx,const Val & val) const82   Result<std::monostate> set(Store::Context cx, uint64_t idx,
83                              const Val &val) const {
84     auto *error = wasmtime_table_set(cx.ptr, &table, idx, &val.val);
85     if (error != nullptr) {
86       return Error(error);
87     }
88     return std::monostate();
89   }
90 
91   /// Grow this table.
92   ///
93   /// \param cx the store that owns this table.
94   /// \param delta the number of new elements to be added to this table.
95   /// \param init the initial value of all new elements in this table.
96   ///
97   /// Returns an error if `init` has the wrong type for this table. Otherwise
98   /// returns the previous size of the table before growth.
grow(Store::Context cx,uint64_t delta,const Val & init) const99   Result<uint64_t> grow(Store::Context cx, uint64_t delta,
100                         const Val &init) const {
101     uint64_t prev = 0;
102     auto *error = wasmtime_table_grow(cx.ptr, &table, delta, &init.val, &prev);
103     if (error != nullptr) {
104       return Error(error);
105     }
106     return prev;
107   }
108 
109   /// Returns the raw underlying C API table this is using.
capi() const110   const wasmtime_table_t &capi() const { return table; }
111 };
112 
113 } // namespace wasmtime
114 
115 #endif // WASMTIME_TABLE_HH
116