Skip to content

Commit 9e449de

Browse files
committed
WIP
1 parent 15f06d1 commit 9e449de

File tree

10 files changed

+170
-66
lines changed

10 files changed

+170
-66
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ endif()
1010

1111
enable_testing()
1212

13+
set(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
14+
1315
add_subdirectory(src)
1416
add_subdirectory(test)

src/lift.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "list.hpp"
99
#include "flags.hpp"
1010
#include "record.hpp"
11+
#include "variant.hpp"
1112
#include "util.hpp"
1213

1314
namespace cmcpp
@@ -66,6 +67,12 @@ namespace cmcpp
6667
auto x = record::lift_flat<T>(cx, vi);
6768
return x;
6869
}
70+
71+
template <Variant T>
72+
T lift_flat(const CallContext &cx, const WasmValVectorIterator &vi)
73+
{
74+
return variant::lift_flat<T>(cx, vi);
75+
}
6976
}
7077

7178
#endif

src/list.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ namespace cmcpp
5757
}
5858

5959
template <typename T>
60-
WasmValVector lower_flat(CallContext &cx, const list_t<T> &v)
60+
WasmValVector lower_flat_list(CallContext &cx, const list_t<T> &v)
6161
{
6262
auto [ptr, length] = store_into_range(cx, v);
6363
return {static_cast<int32_t>(ptr), static_cast<int32_t>(length)};

src/lower.hpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ namespace cmcpp
5757
template <List T>
5858
inline WasmValVector lower_flat(CallContext &cx, const T &v)
5959
{
60-
return list::lower_flat(cx, v);
60+
return list::lower_flat_list(cx, v);
6161
}
6262

6363
template <Flags T>
@@ -69,7 +69,23 @@ namespace cmcpp
6969
template <Record T>
7070
inline WasmValVector lower_flat(CallContext &cx, const T &v)
7171
{
72-
return record::lower_flat(cx, v);
72+
return record::lower_flat_record(cx, v);
73+
}
74+
75+
template <Variant T>
76+
inline WasmValVector lower_flat(CallContext &cx, const T &v)
77+
{
78+
return variant::lower_flat_variant(cx, v);
79+
}
80+
81+
template <Field T>
82+
inline WasmValVector lower_flat_field(CallContext &cx, const T &v)
83+
{
84+
switch (ValTrait<T>::type)
85+
{
86+
default:
87+
return {};
88+
}
7389
}
7490
}
7591

src/record.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace cmcpp
1717
{
1818

1919
template <Record T>
20-
void store(const CallContext &cx, const T&v, uint32_t ptr)
20+
void store(const CallContext &cx, const T &v, uint32_t ptr)
2121
{
2222
auto process_field = [&](auto &&field)
2323
{
@@ -31,7 +31,7 @@ namespace cmcpp
3131
}
3232

3333
template <Record T>
34-
WasmValVector lower_flat(CallContext &cx, const T &v)
34+
WasmValVector lower_flat_record(CallContext &cx, const T &v)
3535
{
3636
WasmValVector retVal = {};
3737
auto process_field = [&](auto &&field)

src/traits.hpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ namespace cmcpp
170170

171171
template <typename T>
172172
concept Char = ValTrait<T>::type == ValType::Char;
173-
// Numerics --------------------------------------------------------------------
174173

174+
// Numerics --------------------------------------------------------------------
175175
template <>
176176
struct ValTrait<int8_t>
177177
{
@@ -381,6 +381,7 @@ namespace cmcpp
381381

382382
template <typename T>
383383
concept String = ValTrait<T>::type == ValType::String;
384+
384385
// List --------------------------------------------------------------------
385386
template <typename T>
386387
using list_t = std::vector<T>;
@@ -396,6 +397,7 @@ namespace cmcpp
396397
};
397398
template <typename T>
398399
concept List = ValTrait<T>::type == ValType::List;
400+
399401
// Flags --------------------------------------------------------------------
400402
template <size_t N>
401403
struct StringLiteral
@@ -486,10 +488,12 @@ namespace cmcpp
486488

487489
template <typename T>
488490
concept Flags = ValTrait<T>::type == ValType::Flags;
489-
// Record --------------------------------------------------------------------
491+
492+
// Field --------------------------------------------------------------------
490493
template <typename T>
491494
concept Field = ValTrait<T>::type != ValType::UNKNOWN;
492495

496+
// Record --------------------------------------------------------------------
493497
template <Field... Ts>
494498
using record_t = std::tuple<Ts...>;
495499
template <Field... Ts>
@@ -514,18 +518,40 @@ namespace cmcpp
514518
}
515519

516520
// Variant ------------------------------------------------------------------
517-
518521
template <Field... Ts>
519-
using variant_t = std::variant<Ts...>;
522+
struct variant_t
523+
{
524+
using types = std::variant<Ts...>;
525+
types value;
526+
527+
template <Field T>
528+
variant_t(const T &v) : value(v)
529+
{
530+
static_assert((std::is_same_v<T, types> || ...), "Invalid type for variant");
531+
}
532+
};
520533
template <Field... Ts>
521534
struct ValTrait<variant_t<Ts...>>
522535
{
523536
static constexpr ValType type = ValType::Variant;
524-
using inner_type = typename std::variant<Ts...>;
537+
// using inner_type = std::decay_t<std::variant<Ts...>>;
525538
};
526539
template <typename T>
527540
concept Variant = ValTrait<T>::type == ValType::Variant;
528541

542+
template <Variant T>
543+
constexpr ValType variant_type(const T &v)
544+
{
545+
return std::visit([](auto &&arg) -> ValType
546+
{ return ValTrait<std::decay_t<decltype(arg)>>::type; }, v);
547+
}
548+
template <Variant T>
549+
constexpr size_t variant_index(const T &v)
550+
{
551+
return std::visit([](auto &&arg) -> size_t
552+
{ return arg.index(); }, v);
553+
}
554+
529555
// Other --------------------------------------------------------------------
530556

531557
// template <typename... Ts>

src/variant.hpp

Lines changed: 72 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "store.hpp"
77
#include "load.hpp"
88
#include "util.hpp"
9+
#include "util.hpp"
910

1011
#include <tuple>
1112
#include <limits>
@@ -15,11 +16,13 @@ namespace cmcpp
1516
{
1617
namespace variant
1718
{
19+
1820
// template <Variant T>
19-
// std::pair<int, std::optional<typename T::value_type>> match_case(const T &v)
21+
// std::pair<int, typename ValTrait<T>::inner_type> match_case(const T &v)
2022
// {
2123
// auto index = v.index();
22-
// auto value = std::get<index>(v);
24+
// auto value = std::visit([](auto &&arg) -> typename ValTrait<T>::inner_type
25+
// { return arg; }, v);
2326
// return {index, value};
2427
// }
2528

@@ -64,62 +67,78 @@ namespace cmcpp
6467
// WasmValVector flatten_variant(const T &v)
6568
// {
6669
// WasmValVector flat;
67-
// std::visit([&](auto &&arg) {
70+
// std::visit([&](auto &&arg)
71+
// {
6872
// using V = std::decay_t<decltype(arg)>;
6973
// auto f = lower_flat(arg);
70-
// flat.insert(flat.end(), f.begin(), f.end());
71-
// }, v);
74+
// flat.insert(flat.end(), f.begin(), f.end()); }, v);
7275
// }
7376

77+
template <Variant T>
78+
WasmValVector lower_flat_variant(CallContext &cx, const T &v)
79+
{
80+
WasmValVector retVal = {};
81+
ValType t = variant_type(v);
82+
// auto index = variant_index(v);
83+
// auto value = std::get<ValTrait<T>::index>(v);
84+
// auto value = variant_value(v, index);
85+
// ValTrait<T>::inner_type v = 42;
86+
// auto value = std::get<typename ValTrait<T>::inner_type>(v);
7487

75-
// template <Variant T>
76-
// void lower_flat(CallContext &cx, const T &v, uint32_t ptr)
77-
// {
78-
// auto [case_index, case_value] = match_case(v);
79-
// std::vector<std::string> flat_types = flatten_variant(v);
80-
// assert(flat_types[0] == "i32");
81-
// flat_types.erase(flat_types.begin());
82-
// auto c = cases[case_index];
83-
// std::vector<WasmVal> payload;
84-
// if (c->v.has_value())
85-
// {
86-
// payload = lower_flat(cx, case_value.value(), c->v.value());
87-
// auto vTypes = flatten_type(c->v.value());
88-
// for (size_t i = 0; i < payload.size(); ++i)
89-
// {
90-
// auto fv = payload[i];
91-
// auto have = vTypes[i];
92-
// auto want = flat_types[0];
93-
// flat_types.erase(flat_types.begin());
94-
// if (have == "f32" && want == "i32")
95-
// {
96-
// payload[i] = encode_float_as_i32(std::get<float32_t>(fv));
97-
// }
98-
// else if (have == "i32" && want == "i64")
99-
// {
100-
// payload[i] = fv;
101-
// }
102-
// else if (have == "f32" && want == "i64")
103-
// {
104-
// payload[i] = encode_float_as_i32(std::get<float32_t>(fv));
105-
// }
106-
// else if (have == "f64" && want == "i64")
107-
// {
108-
// payload[i] = static_cast<int64_t>(encode_float_as_i64(std::get<float64_t>(fv)));
109-
// }
110-
// else
111-
// {
112-
// assert(have == want);
113-
// }
114-
// }
115-
// }
116-
// for (auto _ : flat_types)
117-
// {
118-
// payload.push_back(0);
119-
// }
120-
// payload.insert(payload.begin(), case_index);
121-
// return payload;
122-
// }
88+
// auto [case_index, case_value] = match_case(v);
89+
// auto payload = cmcpp::lower_flat(cx, value);
90+
// auto flat_types = flatten_variant(v);
91+
// assert(flat_types[0] == "i32");
92+
// flat_types.erase(flat_types.begin());
93+
// auto c = cases[case_index];
94+
// std::vector<WasmVal> payload;
95+
// if (c->v.has_value())
96+
// {
97+
// payload = lower_flat(cx, case_value.value(), c->v.value());
98+
// auto vTypes = flatten_type(c->v.value());
99+
// for (size_t i = 0; i < payload.size(); ++i)
100+
// {
101+
// auto fv = payload[i];
102+
// auto have = vTypes[i];
103+
// auto want = flat_types[0];
104+
// flat_types.erase(flat_types.begin());
105+
// if (have == "f32" && want == "i32")
106+
// {
107+
// payload[i] = encode_float_as_i32(std::get<float32_t>(fv));
108+
// }
109+
// else if (have == "i32" && want == "i64")
110+
// {
111+
// payload[i] = fv;
112+
// }
113+
// else if (have == "f32" && want == "i64")
114+
// {
115+
// payload[i] = encode_float_as_i32(std::get<float32_t>(fv));
116+
// }
117+
// else if (have == "f64" && want == "i64")
118+
// {
119+
// payload[i] = static_cast<int64_t>(encode_float_as_i64(std::get<float64_t>(fv)));
120+
// }
121+
// else
122+
// {
123+
// assert(have == want);
124+
// }
125+
// }
126+
// }
127+
// for (auto _ : flat_types)
128+
// {
129+
// payload.push_back(0);
130+
// }
131+
// payload.insert(payload.begin(), case_index);
132+
// return payload;
133+
return retVal;
134+
}
135+
136+
template <Variant T>
137+
inline T lift_flat(const CallContext &cx, const WasmValVectorIterator &vi)
138+
{
139+
T retVal;
140+
return retVal;
141+
}
123142
}
124143
}
125144

test/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
1111
add_link_options(-fprofile-instr-generate)
1212
endif()
1313

14-
1514
find_package(doctest CONFIG REQUIRED)
1615
find_package(ICU REQUIRED COMPONENTS uc dt in io)
1716

1817
include_directories(
19-
../src
18+
${ROOT_DIR}/src
2019
${ICU_INCLUDE_DIR}
2120
)
2221

test/main.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,3 +418,38 @@ TEST_CASE("Records")
418418
auto rr0 = to_struct<MyRecord0>(rr);
419419
}
420420

421+
TEST_CASE("Variant")
422+
{
423+
Heap heap(1024 * 1024);
424+
auto cx = createCallContext(&heap, Encoding::Utf8);
425+
426+
using V0 = variant_t<uint16_t, uint32_t>;
427+
V0 v0 = static_cast<uint16_t>(42);
428+
auto vv0 = lower_flat(*cx, v0);
429+
auto v00 = lift_flat<V0>(*cx, vv0);
430+
CHECK(v0 == v00);
431+
432+
using V1 = variant_t<uint16_t, uint32_t, string_t>;
433+
V1 v1 = "Hello";
434+
auto vv1 = lower_flat(*cx, v1);
435+
auto v11 = lift_flat<V1>(*cx, vv1);
436+
CHECK(v1 == v11);
437+
438+
using V2 = variant_t<uint16_t, uint32_t, string_t, list_t<string_t>>;
439+
V2 v2 = list_t<string_t>{"Hello", "World", "!"};
440+
auto vv2 = lower_flat(*cx, v2);
441+
auto v22 = lift_flat<V2>(*cx, vv2);
442+
CHECK(v2 == v22);
443+
444+
using V3 = variant_t<uint16_t, uint32_t, string_t, list_t<string_t>, record_t<uint16_t, uint32_t>>;
445+
V3 v3 = record_t<uint16_t, uint32_t>{42, 43};
446+
auto vv3 = lower_flat(*cx, v3);
447+
auto v33 = lift_flat<V3>(*cx, vv3);
448+
CHECK(v3 == v33);
449+
450+
using V4 = variant_t<uint16_t, uint32_t, string_t, list_t<string_t>, record_t<uint16_t, uint32_t>, V3>;
451+
V4 v4 = record_t<uint16_t, uint32_t>{42, 43};
452+
auto vv4 = lower_flat(*cx, v4);
453+
auto v44 = lift_flat<V4>(*cx, vv4);
454+
CHECK(v4 == v44);
455+
}

0 commit comments

Comments
 (0)