@@ -38,6 +38,34 @@ public:
3838 // / Creates a new `ExternRef` directly from its C-API representation.
3939 explicit ExternRef (wasmtime_externref_t val) : val(val) {}
4040
41+ // / Copy constructor to clone `other`.
42+ ExternRef (const ExternRef &other) {
43+ wasmtime_externref_clone (NULL , &other.val , &val);
44+ }
45+
46+ // / Copy assignment to clone from `other`.
47+ ExternRef &operator =(const ExternRef &other) {
48+ wasmtime_externref_unroot (NULL , &val);
49+ wasmtime_externref_clone (NULL , &other.val , &val);
50+ return *this ;
51+ }
52+
53+ // / Move constructor to move the contents of `other`.
54+ ExternRef (ExternRef &&other) {
55+ val = other.val ;
56+ wasmtime_externref_set_null (&other.val );
57+ }
58+
59+ // / Move assignment to move the contents of `other`.
60+ ExternRef &operator =(ExternRef &&other) {
61+ wasmtime_externref_unroot (NULL , &val);
62+ val = other.val ;
63+ wasmtime_externref_set_null (&other.val );
64+ return *this ;
65+ }
66+
67+ ~ExternRef () { wasmtime_externref_unroot (NULL , &val); }
68+
4169 // / Creates a new `externref` value from the provided argument.
4270 // /
4371 // / Note that `val` should be safe to send across threads and should own any
@@ -54,9 +82,8 @@ public:
5482
5583 // / Creates a new `ExternRef` which is separately rooted from this one.
5684 ExternRef clone (Store::Context cx) {
57- wasmtime_externref_t other;
58- wasmtime_externref_clone (cx.ptr , &val, &other);
59- return ExternRef (other);
85+ (void )cx;
86+ return *this ;
6087 }
6188
6289 // / Returns the underlying host data associated with this `ExternRef`.
@@ -66,12 +93,24 @@ public:
6693
6794 // / Unroots this value from the context provided, enabling a future GC to
6895 // / collect the internal object if there are no more references.
69- void unroot (Store::Context cx) { wasmtime_externref_unroot (cx.ptr , &val); }
96+ void unroot (Store::Context cx) {
97+ (void )cx;
98+ wasmtime_externref_unroot (NULL , &val);
99+ wasmtime_externref_set_null (&val);
100+ }
70101
71102 // / Returns the raw underlying C API value.
72103 // /
73104 // / This class still retains ownership of the pointer.
74105 const wasmtime_externref_t *raw () const { return &val; }
106+
107+ // / Consumes ownership of the underlying `wasmtime_externref_t` and returns
108+ // / the result of `wasmtime_externref_to_raw`.
109+ uint32_t take_raw (Store::Context cx) {
110+ uint32_t ret = wasmtime_externref_to_raw (cx.raw_context (), &val);
111+ wasmtime_externref_set_null (&val);
112+ return ret;
113+ }
75114};
76115
77116/* *
@@ -86,6 +125,32 @@ public:
86125 // / Creates a new `AnyRef` directly from its C-API representation.
87126 explicit AnyRef (wasmtime_anyref_t val) : val(val) {}
88127
128+ // / Copy constructor to clone `other`.
129+ AnyRef (const AnyRef &other) { wasmtime_anyref_clone (NULL , &other.val , &val); }
130+
131+ // / Copy assignment to clone from `other`.
132+ AnyRef &operator =(const AnyRef &other) {
133+ wasmtime_anyref_unroot (NULL , &val);
134+ wasmtime_anyref_clone (NULL , &other.val , &val);
135+ return *this ;
136+ }
137+
138+ // / Move constructor to move the contents of `other`.
139+ AnyRef (AnyRef &&other) {
140+ val = other.val ;
141+ wasmtime_anyref_set_null (&other.val );
142+ }
143+
144+ // / Move assignment to move the contents of `other`.
145+ AnyRef &operator =(AnyRef &&other) {
146+ wasmtime_anyref_unroot (NULL , &val);
147+ val = other.val ;
148+ wasmtime_anyref_set_null (&other.val );
149+ return *this ;
150+ }
151+
152+ ~AnyRef () { wasmtime_anyref_unroot (NULL , &val); }
153+
89154 // / Creates a new `AnyRef` which is an `i31` with the given `value`,
90155 // / truncated if the upper bit is set.
91156 static AnyRef i31 (Store::Context cx, uint32_t value) {
@@ -96,14 +161,17 @@ public:
96161
97162 // / Creates a new `AnyRef` which is separately rooted from this one.
98163 AnyRef clone (Store::Context cx) {
99- wasmtime_anyref_t other;
100- wasmtime_anyref_clone (cx.ptr , &val, &other);
101- return AnyRef (other);
164+ (void )cx;
165+ return *this ;
102166 }
103167
104168 // / Unroots this value from the context provided, enabling a future GC to
105169 // / collect the internal object if there are no more references.
106- void unroot (Store::Context cx) { wasmtime_anyref_unroot (cx.ptr , &val); }
170+ void unroot (Store::Context cx) {
171+ (void )cx;
172+ wasmtime_anyref_unroot (NULL , &val);
173+ wasmtime_anyref_set_null (&val);
174+ }
107175
108176 // / Returns the raw underlying C API value.
109177 // /
@@ -201,6 +269,7 @@ public:
201269 val.kind = WASMTIME_EXTERNREF;
202270 if (ptr) {
203271 val.of .externref = ptr->val ;
272+ wasmtime_externref_set_null (&ptr->val );
204273 } else {
205274 wasmtime_externref_set_null (&val.of .externref );
206275 }
@@ -210,6 +279,7 @@ public:
210279 val.kind = WASMTIME_ANYREF;
211280 if (ptr) {
212281 val.of .anyref = ptr->val ;
282+ wasmtime_anyref_set_null (&ptr->val );
213283 } else {
214284 wasmtime_anyref_set_null (&val.of .anyref );
215285 }
@@ -221,6 +291,35 @@ public:
221291 // / any`.
222292 Val (AnyRef ptr);
223293
294+ // / Copy constructor to clone `other`.
295+ Val (const Val &other) { wasmtime_val_clone (NULL , &other.val , &val); }
296+
297+ // / Copy assignment to clone from `other`.
298+ Val &operator =(const Val &other) {
299+ wasmtime_val_unroot (NULL , &val);
300+ wasmtime_val_clone (NULL , &other.val , &val);
301+ return *this ;
302+ }
303+
304+ // / Move constructor to move the contents of `other`.
305+ Val (Val &&other) {
306+ val = other.val ;
307+ other.val .kind = WASMTIME_I32;
308+ other.val .of .i32 = 0 ;
309+ }
310+
311+ // / Move assignment to move the contents of `other`.
312+ Val &operator =(Val &&other) {
313+ wasmtime_val_unroot (NULL , &val);
314+ val = other.val ;
315+ other.val .kind = WASMTIME_I32;
316+ other.val .of .i32 = 0 ;
317+ return *this ;
318+ }
319+
320+ // / Unroots the values in `val`, if any.
321+ ~Val () { wasmtime_val_unroot (NULL , &val); }
322+
224323 // / Returns the kind of value that this value has.
225324 ValKind kind () const {
226325 switch (val.kind ) {
@@ -295,14 +394,15 @@ public:
295394 // / Note that `externref` is a nullable reference, hence the `optional` return
296395 // / value.
297396 std::optional<ExternRef> externref (Store::Context cx) const {
397+ (void )cx;
298398 if (val.kind != WASMTIME_EXTERNREF) {
299399 std::abort ();
300400 }
301401 if (wasmtime_externref_is_null (&val.of .externref )) {
302402 return std::nullopt ;
303403 }
304404 wasmtime_externref_t other;
305- wasmtime_externref_clone (cx. ptr , &val.of .externref , &other);
405+ wasmtime_externref_clone (NULL , &val.of .externref , &other);
306406 return ExternRef (other);
307407 }
308408
@@ -312,14 +412,15 @@ public:
312412 // / Note that `anyref` is a nullable reference, hence the `optional` return
313413 // / value.
314414 std::optional<AnyRef> anyref (Store::Context cx) const {
415+ (void )cx;
315416 if (val.kind != WASMTIME_ANYREF) {
316417 std::abort ();
317418 }
318419 if (wasmtime_anyref_is_null (&val.of .anyref )) {
319420 return std::nullopt ;
320421 }
321422 wasmtime_anyref_t other;
322- wasmtime_anyref_clone (cx. ptr , &val.of .anyref , &other);
423+ wasmtime_anyref_clone (NULL , &val.of .anyref , &other);
323424 return AnyRef (other);
324425 }
325426
@@ -331,7 +432,12 @@ public:
331432 std::optional<Func> funcref () const ;
332433
333434 // / Unroots any GC references this `Val` points to within the `cx` provided.
334- void unroot (Store::Context cx) { wasmtime_val_unroot (cx.ptr , &val); }
435+ void unroot (Store::Context cx) {
436+ (void )cx;
437+ wasmtime_val_unroot (NULL , &val);
438+ val.kind = WASMTIME_I32;
439+ val.of .i32 = 0 ;
440+ }
335441};
336442
337443} // namespace wasmtime
0 commit comments