Skip to content

Commit aafecab

Browse files
committed
chore: More wit -> wamr thunking
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
1 parent 4de8818 commit aafecab

7 files changed

Lines changed: 235 additions & 19 deletions

File tree

include/cmcpp/list.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ namespace cmcpp
8282
list_t<T> lift_flat(const CallContext &cx, const CoreValueIter &vi)
8383
{
8484
auto ptr = vi.next<int32_t>();
85+
if (vi.done())
86+
{
87+
return cmcpp::list::load<T>(cx, ptr);
88+
}
8589
auto length = vi.next<int32_t>();
8690
return load_from_range<T>(cx, ptr, length);
8791
}

include/cmcpp/string.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,11 @@ namespace cmcpp
319319
template <String T>
320320
T lift_flat(const CallContext &cx, const CoreValueIter &vi)
321321
{
322-
323322
auto ptr = vi.next<int32_t>();
323+
if (vi.done())
324+
{
325+
return cmcpp::string::load<T>(cx, ptr);
326+
}
324327
auto packed_length = vi.next<int32_t>();
325328
return load_from_range<T>(cx, ptr, packed_length);
326329
}

include/cmcpp/traits.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ namespace cmcpp
137137
Option,
138138
Result,
139139
Flags,
140+
Func,
140141
Own,
141142
Borrow,
142143
LAST
@@ -690,6 +691,21 @@ namespace cmcpp
690691
template <typename T>
691692
concept Option = ValTrait<T>::type == ValType::Option;
692693

694+
// Func --------------------------------------------------------------------
695+
template <Field R, Field... Args>
696+
using func_t = std::function<R(Args...)>;
697+
template <Field R, Field... Args>
698+
struct ValTrait<func_t<R, Args...>>
699+
{
700+
static constexpr ValType type = ValType::Func;
701+
using params_t = tuple_t<Args...>;
702+
using result_t = R;
703+
static constexpr auto flat_params_types = ValTrait<params_t>::flat_types;
704+
static constexpr auto flat_result_types = ValTrait<result_t>::flat_types;
705+
};
706+
template <typename T>
707+
concept Func = ValTrait<T>::type == ValType::Func;
708+
693709
// --------------------------------------------------------------------
694710

695711
using offset = uint32_t;

include/cmcpp/util.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ namespace cmcpp
6464
assert(it != end);
6565
return *it++;
6666
}
67+
bool done() const
68+
{
69+
return !(it != end);
70+
}
6771
};
6872

6973
}

samples/wamr/main.cpp

Lines changed: 160 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,78 @@ std::pair<void *, size_t> convert(void *dest, uint32_t dest_byte_len, const void
5151
assert(false);
5252
}
5353

54-
int main()
54+
std::vector<wasm_val_t> toWamr(const WasmValVector &values)
55+
{
56+
std::vector<wasm_val_t> result(values.size());
57+
for (size_t i = 0; i < values.size(); i++)
58+
{
59+
switch (values[i].index())
60+
{
61+
case WASM_I32:
62+
result[i].kind = WASM_I32;
63+
result[i].of.i32 = std::get<int32_t>(values[i]);
64+
break;
65+
case WASM_I64:
66+
result[i].kind = WASM_I64;
67+
result[i].of.i64 = std::get<int64_t>(values[i]);
68+
break;
69+
case WASM_F32:
70+
result[i].kind = WASM_F32;
71+
result[i].of.f32 = std::get<float>(values[i]);
72+
break;
73+
case WASM_F64:
74+
result[i].kind = WASM_F64;
75+
result[i].of.f64 = std::get<double>(values[i]);
76+
break;
77+
default:
78+
assert(false);
79+
}
80+
}
81+
return result;
82+
}
83+
84+
template <typename T>
85+
WasmValVector fromWamr(size_t count, const wasm_val_t *values)
5586
{
56-
std::cout << "Hello, World!" << std::endl;
87+
auto size = ValTrait<T>::size;
88+
auto alignment = ValTrait<T>::alignment;
89+
auto target_count = ValTrait<T>::flat_types.size();
5790

91+
WasmValVector result(count);
92+
for (size_t i = 0; i < count; i++)
93+
{
94+
switch (values[i].kind)
95+
{
96+
case WASM_I32:
97+
result[i] = values[i].of.i32;
98+
break;
99+
case WASM_I64:
100+
result[i] = values[i].of.i64;
101+
break;
102+
case WASM_F32:
103+
result[i] = values[i].of.f32;
104+
break;
105+
case WASM_F64:
106+
result[i] = values[i].of.f64;
107+
break;
108+
default:
109+
std::cout << "values[i].kind: " << values[i].kind << std::endl;
110+
assert(false);
111+
}
112+
}
113+
// for (size_t i = count; i < target_count; i++)
114+
// {
115+
// result[i] = (int32_t)(std::get<int32_t>(result[count - 1]) + (i * alignment));
116+
// }
117+
return result;
118+
}
119+
120+
int main()
121+
{
58122
char *buffer, error_buf[128];
59123
wasm_module_t module;
60124
wasm_module_inst_t module_inst;
61-
wasm_function_inst_t cabi_realloc, func;
125+
wasm_function_inst_t cabi_realloc;
62126
wasm_exec_env_t exec_env;
63127
uint32_t size, stack_size = 8092, heap_size = 8092;
64128

@@ -104,19 +168,101 @@ int main()
104168
.post_return = nullptr,
105169
};
106170

107-
func = wasm_runtime_lookup_function(module_inst, "example:sample/boolean#and");
171+
using and_func_t = std::function<bool_t(bool_t, bool_t)>;
172+
auto and_func = wasm_runtime_lookup_function(module_inst, "example:sample/booleans#and");
173+
and_func_t call_and = [&](bool_t a, bool_t b) -> bool_t
174+
{
175+
using inputs_t = ValTrait<and_func_t>::params_t;
176+
using outputs_t = ValTrait<and_func_t>::result_t;
177+
auto inputs = toWamr(lower_flat(callContext, inputs_t{a, b}));
178+
auto output_size = 1;
179+
wasm_val_t outputs[output_size];
180+
auto call_result = wasm_runtime_call_wasm_a(exec_env, and_func, output_size, outputs, inputs.size(), inputs.data());
181+
auto result = lift_flat<outputs_t>(callContext, fromWamr<outputs_t>(output_size, outputs));
182+
std::cout << "and_func(" << a << ", " << b << "): " << result << std::endl;
183+
return result;
184+
};
185+
call_and(false, false);
186+
call_and(false, true);
187+
call_and(true, false);
188+
call_and(true, true);
189+
190+
using add_func_t = std::function<float64_t(float64_t, float64_t)>;
191+
auto add_func = wasm_runtime_lookup_function(module_inst, "example:sample/floats#add");
192+
add_func_t call_add = [&](float64_t input1, float64_t input2) -> float64_t
193+
{
194+
using inputs_t = ValTrait<add_func_t>::params_t;
195+
using outputs_t = ValTrait<add_func_t>::result_t;
196+
197+
auto inputs = toWamr(lower_flat(callContext, inputs_t{input1, input2}));
198+
auto output_size = 1;
199+
wasm_val_t outputs[output_size];
200+
auto call_result = wasm_runtime_call_wasm_a(exec_env, add_func, output_size, outputs, inputs.size(), inputs.data());
201+
auto result = lift_flat<outputs_t>(callContext, fromWamr<outputs_t>(output_size, outputs));
202+
std::cout << "add_func(" << input1 << ", " << input2 << "): " << result << std::endl;
203+
return result;
204+
};
205+
call_add(3.1, 0.2);
206+
207+
using reverse_func_t = std::function<string_t(string_t)>;
208+
auto reverse_func = wasm_runtime_lookup_function(module_inst, "example:sample/strings#reverse");
209+
auto reverse_cleanup_func = wasm_runtime_lookup_function(module_inst, "cabi_post_example:sample/strings#reverse");
210+
reverse_func_t call_reverse = [&](string_t input1) -> string_t
211+
{
212+
using inputs_t = ValTrait<reverse_func_t>::params_t;
213+
using outputs_t = ValTrait<reverse_func_t>::result_t;
108214

109-
// bool_t arg1 = true;
110-
// bool_t arg2 = false;
111-
// auto args_flat = cmcpp::lower_flat(callContext, args);
112-
uint32_t argv[2] = {true, false};
215+
auto inputs = toWamr(lower_flat(callContext, inputs_t{input1}));
216+
auto output_size = 1;
217+
wasm_val_t outputs[output_size];
218+
auto call_result = wasm_runtime_call_wasm_a(exec_env, reverse_func, output_size, outputs, inputs.size(), inputs.data());
219+
// auto result = load<outputs_t>(callContext, outputs[0].of.i32);
220+
auto result = lift_flat<outputs_t>(callContext, fromWamr<outputs_t>(output_size, outputs));
221+
std::cout << "reverse_string(" << input1 << "): " << result << std::endl;
222+
call_result = wasm_runtime_call_wasm_a(exec_env, reverse_cleanup_func, 0, nullptr, 1, outputs);
223+
return result;
224+
};
225+
auto call_reverse_result = call_reverse("Hello World!");
226+
call_reverse(call_reverse_result);
227+
228+
using reverse_tuple_func_t = std::function<tuple_t<string_t, bool_t>(tuple_t<bool_t, string_t>)>;
229+
auto reverse_tuple_func = wasm_runtime_lookup_function(module_inst, "example:sample/tuples#reverse");
230+
auto reverse_tuple_cleanup_func = wasm_runtime_lookup_function(module_inst, "cabi_post_example:sample/tuples#reverse");
231+
reverse_tuple_func_t call_reverse_tuple = [&](tuple_t<bool_t, string_t> a) -> tuple_t<string_t, bool_t>
232+
{
233+
using inputs_t = ValTrait<reverse_tuple_func_t>::params_t;
234+
using outputs_t = ValTrait<reverse_tuple_func_t>::result_t;
235+
236+
auto inputs = toWamr(lower_flat(callContext, a));
237+
auto output_size = 1;
238+
wasm_val_t outputs[output_size];
239+
auto call_result = wasm_runtime_call_wasm_a(exec_env, reverse_tuple_func, output_size, outputs, inputs.size(), inputs.data());
240+
auto result = load<outputs_t>(callContext, outputs->of.i32);
241+
std::cout << "reverse_tuple(" << std::get<0>(a) << ", " << std::get<1>(a) << "): " << std::get<0>(result) << ", " << std::get<1>(result) << std::endl;
242+
call_result = wasm_runtime_call_wasm_a(exec_env, reverse_tuple_cleanup_func, 0, nullptr, 1, outputs);
243+
return result;
244+
};
245+
auto call_reverse_tuple_result = call_reverse_tuple({false, "Hello World!"});
246+
// call_reverse_tuple({std::get<1>(call_reverse_tuple_result), std::get<0>(call_reverse_tuple_result}));
247+
248+
using list_filter_bool_func_t = std::function<list_t<string_t>(list_t<variant_t<bool_t, string_t>>)>;
249+
auto list_filter_bool_func = wasm_runtime_lookup_function(module_inst, "example:sample/lists#filter-bool");
250+
auto list_filter_bool_cleanup_func = wasm_runtime_lookup_function(module_inst, "cabi_post_example:sample/lists#filter-bool");
251+
auto call_list_filter_bool = [&](list_t<variant_t<bool_t, string_t>> a) -> list_t<string_t>
252+
{
253+
using inputs_t = ValTrait<list_filter_bool_func_t>::params_t;
254+
using outputs_t = ValTrait<list_filter_bool_func_t>::result_t;
113255

114-
list_t<variant_t<bool_t>> args = {true, false};
115-
auto args_flat = cmcpp::lower_flat(callContext, args);
116-
auto call_result = wasm_runtime_call_wasm(exec_env, func, 2, (uint32_t *)args_flat.data());
117-
args_flat.resize(1);
118-
auto result = cmcpp::lift_flat<bool_t>(callContext, args_flat);
119-
std::cout << "Result: " << result << std::endl;
256+
auto inputs = toWamr(lower_flat(callContext, a));
257+
auto output_size = 1;
258+
wasm_val_t outputs[output_size];
259+
auto call_result = wasm_runtime_call_wasm_a(exec_env, list_filter_bool_func, output_size, outputs, inputs.size(), inputs.data());
260+
auto result = lift_flat<outputs_t>(callContext, fromWamr<outputs_t>(output_size, outputs));
261+
std::cout << "list_filter_bool(" << a.size() << "): " << result.size() << std::endl;
262+
call_result = wasm_runtime_call_wasm_a(exec_env, list_filter_bool_cleanup_func, 0, nullptr, 1, outputs);
263+
return result;
264+
};
265+
auto call_list_filter_bool_result = call_list_filter_bool({{false}, {"Hello World!"}});
120266

121267
wasm_runtime_destroy_exec_env(exec_env);
122268
wasm_runtime_deinstantiate(module_inst);

samples/wasm/main.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33
#include <cstdlib>
44

5-
bool exports_example_sample_boolean_and(bool a, bool b)
5+
bool exports_example_sample_booleans_and(bool a, bool b)
66
{
77
return a && b;
88
}
99

10+
double exports_example_sample_floats_add(double a, double b)
11+
{
12+
return a + b;
13+
}
14+
1015
void exports_example_sample_strings_reverse(sample_string_t *a, sample_string_t *ret)
1116
{
1217
ret->ptr = (uint8_t *)malloc(a->len);
@@ -15,4 +20,23 @@ void exports_example_sample_strings_reverse(sample_string_t *a, sample_string_t
1520
{
1621
ret->ptr[i] = a->ptr[a->len - i - 1];
1722
}
18-
}
23+
}
24+
25+
void exports_example_sample_tuples_reverse(sample_tuple2_bool_string_t *a, sample_tuple2_string_bool_t *ret)
26+
{
27+
ret->f1 = !a->f0;
28+
exports_example_sample_strings_reverse(&a->f1, &ret->f0);
29+
}
30+
31+
void exports_example_sample_lists_filter_bool(exports_example_sample_lists_list_v_t *a, sample_list_string_t *ret)
32+
{
33+
ret->ptr = (sample_string_t *)malloc(a->len * sizeof(sample_string_t));
34+
ret->len = 0;
35+
for (size_t i = 0; i < a->len; ++i)
36+
{
37+
if (a->ptr[i].tag == EXPORTS_EXAMPLE_SAMPLE_LISTS_V_S)
38+
{
39+
ret->ptr[ret->len++] = a->ptr[i].val.s;
40+
}
41+
}
42+
}

samples/wasm/sample.wit

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
11
package example:sample;
22

3-
interface boolean {
3+
interface booleans {
44
and: func(a: bool, b: bool) -> bool;
55
// export or: func(a: bool, b: bool) -> bool;
66
// export not: func(a: bool) -> bool;
77
}
88

9+
interface floats {
10+
add: func(a: f64, b: f64) -> f64;
11+
}
12+
913
interface strings {
1014
reverse: func(a: string) -> string;
1115
}
1216

17+
interface tuples {
18+
reverse: func(a: tuple<bool, string>) -> tuple<string, bool>;
19+
}
20+
21+
interface lists {
22+
variant v {
23+
b(bool),
24+
s(string)
25+
}
26+
filter-bool: func(a: list<v>) -> list<string>;
27+
}
28+
1329
world sample {
14-
export boolean;
30+
export booleans;
31+
export floats;
1532
export strings;
33+
export tuples;
34+
export lists;
1635
}

0 commit comments

Comments
 (0)