Open
Description
Given a WIT definition which includes a function returning a variant that includes a list:
package local:[email protected];
interface task {
variant value {
a(bool),
b(list<u8>),
}
do-thing: func() -> value;
}
world test {
import task;
}
And generating C++17 bindings using latest master (7f92598
):
wit-bingen cpp test.wit
test.cpp
:
...snip
extern "C" __attribute__((import_module("local:test/[email protected]")))
__attribute__((import_name("do-thing")))
void localX3AtestX2FtaskX400X2E1X2E0X00do_thing(uint8_t *);
local::test::task::Value local::test::task::DoThing()
{
uintptr_t ret_area[((3*sizeof(void*))+sizeof(uintptr_t)-1)/sizeof(uintptr_t)];
uint8_t* ptr0 = (uint8_t*)(&ret_area);
localX3AtestX2FtaskX400X2E1X2E0X00do_thing(ptr0);
Value variant2;
switch ((int32_t) (*((uint8_t*) (ptr0 + 0)))) {
case 0: {
variant2.variants = Value::A{(bool((int32_t) (*((uint8_t*) (ptr0 + sizeof(void*))))))};
} break;
case 1: { auto len1 = *((size_t*) (ptr0 + (2*sizeof(void*))));
variant2.variants = Value::B{wit::vector<uint8_t>((uint8_t*)(*((uint8_t**) (ptr0 + sizeof(void*)))), len1)};
} break;
}
auto result3 = variant2;
return result3;
}
...snip
The bindings are unable to compile, I think due to the copy constructor for the variant that includes the wit::vector
being deleted:
/opt/wasi-sdk/bin/clang++ -std=c++20 -fno-exceptions -Wall -Wextra -Wc++-compat -g --target=wasm32-wasip2 -O2 -I/bindings -c /bindings/test.cpp -o test.o
/bindings/test.cpp:44:6: error: call to implicitly-deleted copy constructor of 'Value'
44 | auto result3 = variant2;
| ^ ~~~~~~~~
/bindings/test_cpp.h:11:22: note: copy constructor of 'Value' is implicitly deleted because field 'variants' has a deleted copy constructor
11 | std::variant<A, B> variants;
...snip
If the copy from the variant2
to result3
object is removed, and we return the variant2
object directly, the code compiles successfully.
Generated `test.cpp` file
// Generated by `wit-bindgen` 0.43.0. DO NOT EDIT!
// Ensure that the *_component_type.o object is linked in
#ifdef __wasm32__
extern "C" void __component_type_object_force_link_test(void);
__attribute__((used))
void __component_type_object_force_link_test_public_use_in_this_compilation_unit(void) {
__component_type_object_force_link_test();
}
#endif
#include "test_cpp.h"
#include <cstdlib> // realloc
extern "C" void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size);
__attribute__((__weak__, __export_name__("cabi_realloc")))
void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
(void) old_size;
if (new_size == 0) return (void*) align;
void *ret = realloc(ptr, new_size);
if (!ret) abort();
return ret;
}
extern "C" __attribute__((import_module("local:test/[email protected]")))
__attribute__((import_name("do-thing")))
void localX3AtestX2FtaskX400X2E1X2E0X00do_thing(uint8_t *);
local::test::task::Value local::test::task::DoThing()
{
uintptr_t ret_area[((3*sizeof(void*))+sizeof(uintptr_t)-1)/sizeof(uintptr_t)];
uint8_t* ptr0 = (uint8_t*)(&ret_area);
localX3AtestX2FtaskX400X2E1X2E0X00do_thing(ptr0);
Value variant2;
switch ((int32_t) (*((uint8_t*) (ptr0 + 0)))) {
case 0: {
variant2.variants = Value::A{(bool((int32_t) (*((uint8_t*) (ptr0 + sizeof(void*))))))};
} break;
case 1: { auto len1 = *((size_t*) (ptr0 + (2*sizeof(void*))));
variant2.variants = Value::B{wit::vector<uint8_t>((uint8_t*)(*((uint8_t**) (ptr0 + sizeof(void*)))), len1)};
} break;
}
auto result3 = variant2;
return result3;
}
// Component Adapters
Generated `test_cpp.h` file
// Generated by `wit-bindgen` 0.43.0. DO NOT EDIT!
#ifndef __CPP_GUEST_BINDINGS_TEST_H
#define __CPP_GUEST_BINDINGS_TEST_H
#include <cstdint>
#include <utility>
#include <variant>
#include "wit.h"
namespace local {namespace test {namespace task {struct Value {
struct A { bool value; };
struct B { wit::vector<uint8_t> value; };
std::variant<A, B> variants;
};
Value DoThing();
}}}
#endif
Metadata
Metadata
Assignees
Labels
No labels