Skip to content

Simplify function call interface #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 29 additions & 42 deletions example/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,29 @@ void wasm_val_print(wasm_val_t val) {
}

// A function to be called from Wasm code.
void print_callback(const wasm_val_vec_t* args, own wasm_result_t* result) {
printf("Calling back...\n>");
for (size_t i = 0; i < args->size; ++i) {
printf(" ");
wasm_val_print(args->data[i]);
}
own wasm_trap_t* print_callback(
const wasm_val_t args[], wasm_val_t results[]
) {
printf("Calling back...\n> ");
wasm_val_print(args[0]);
printf("\n");

wasm_val_t vals[1];
vals[0].kind = WASM_I32;
vals[0].of.i32 = (int32_t)args->size;
wasm_result_new_vals(result, 1, vals);
wasm_val_copy(&results[0], &args[0]);
return NULL;
}


// A function closure.
void closure_callback(void* env, const wasm_val_vec_t* args, own wasm_result_t* result) {
own wasm_trap_t* closure_callback(
void* env, const wasm_val_t args[], wasm_val_t results[]
) {
int i = *(int*)env;
printf("Calling back closure...\n");
printf("> %d\n", i);

wasm_val_t vals[1];
vals[0].kind = WASM_I32;
vals[0].of.i32 = (int32_t)i;
wasm_result_new_vals(result, 1, vals);
results[0].kind = WASM_I32;
results[0].of.i32 = (int32_t)i;
return NULL;
}


Expand Down Expand Up @@ -94,36 +92,29 @@ int main(int argc, const char* argv[]) {
wasm_byte_vec_delete(&binary);

// Create external print functions.
printf("Creating callbacks...\n");
own wasm_functype_t* print_type1 = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32());
own wasm_func_t* print_func1 = wasm_func_new(store, print_type1, print_callback);

own wasm_functype_t* print_type2 = wasm_functype_new_2_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32());
own wasm_func_t* print_func2 = wasm_func_new(store, print_type2, print_callback);
printf("Creating callback...\n");
own wasm_functype_t* print_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32());
own wasm_func_t* print_func = wasm_func_new(store, print_type, print_callback);

int i = 42;
own wasm_functype_t* closure_type = wasm_functype_new_0_1(wasm_valtype_new_i32());
own wasm_func_t* closure_func = wasm_func_new_with_env(store, closure_type, closure_callback, &i, NULL);

wasm_functype_delete(print_type1);
wasm_functype_delete(print_type2);
wasm_functype_delete(print_type);
wasm_functype_delete(closure_type);

// Instantiate.
printf("Instantiating module...\n");
wasm_extern_t* externs[] = {
wasm_func_as_extern(print_func1), wasm_func_as_extern(print_func2),
wasm_func_as_extern(closure_func)
const wasm_extern_t* imports[] = {
wasm_func_as_extern(print_func), wasm_func_as_extern(closure_func)
};
wasm_extern_vec_t imports = { 3, externs };
own wasm_instance_t* instance = wasm_instance_new(store, module, &imports);
own wasm_instance_t* instance = wasm_instance_new(store, module, imports);
if (!instance) {
printf("> Error instantiating module!\n");
return 1;
}

wasm_func_delete(print_func1);
wasm_func_delete(print_func2);
wasm_func_delete(print_func);
wasm_func_delete(closure_func);

// Extract export.
Expand All @@ -145,15 +136,13 @@ int main(int argc, const char* argv[]) {

// Call.
printf("Calling export...\n");
wasm_val_t vals[2];
vals[0].kind = WASM_I32;
vals[0].of.i32 = 3;
vals[1].kind = WASM_I32;
vals[1].of.i32 = 4;
wasm_val_vec_t args = { 2, vals };
own wasm_result_t result;
wasm_func_call(run_func, &args, &result);
if (result.kind != WASM_RETURN) {
wasm_val_t args[2];
args[0].kind = WASM_I32;
args[0].of.i32 = 3;
args[1].kind = WASM_I32;
args[1].of.i32 = 4;
wasm_val_t results[1];
if (wasm_func_call(run_func, args, results)) {
printf("> Error calling function!\n");
return 1;
}
Expand All @@ -162,9 +151,7 @@ int main(int argc, const char* argv[]) {

// Print result.
printf("Printing result...\n");
printf("> %u\n", result.of.vals.data[0].of.i32);

wasm_result_delete(&result);
printf("> %u\n", results[0].of.i32);

// Shut down.
printf("Shutting down...\n");
Expand Down
45 changes: 19 additions & 26 deletions example/callback.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,24 @@ auto operator<<(std::ostream& out, const wasm::Val& val) -> std::ostream& {
}

// A function to be called from Wasm code.
auto print_callback(const wasm::vec<wasm::Val>& args) -> wasm::Result {
std::cout << "Calling back..." << std::endl << ">";
for (size_t i = 0; i < args.size(); ++i) {
std::cout << " " << args[i];
}
std::cout << std::endl;

int32_t n = args.size();
return wasm::Result(wasm::Val(n));
auto print_callback(
const wasm::Val args[], wasm::Val results[]
) -> wasm::own<wasm::Trap*> {
std::cout << "Calling back..." << std::endl << "> " << args[0] << std::endl;
results[0] = args[0].copy();
return nullptr;
}


// A function closure.
auto closure_callback(void* env, const wasm::vec<wasm::Val>& args) -> wasm::Result {
auto closure_callback(
void* env, const wasm::Val args[], wasm::Val results[]
) -> wasm::own<wasm::Trap*> {
auto i = *reinterpret_cast<int*>(env);
std::cout << "Calling back closure..." << std::endl;
std::cout << "> " << i << std::endl;
return wasm::Result(wasm::Val::i32(static_cast<int32_t>(i)));
results[0] = wasm::Val::i32(static_cast<int32_t>(i));
return nullptr;
}


Expand Down Expand Up @@ -85,18 +85,12 @@ void run() {
}

// Create external print functions.
std::cout << "Creating callbacks..." << std::endl;
auto print_type1 = wasm::FuncType::make(
std::cout << "Creating callback..." << std::endl;
auto print_type = wasm::FuncType::make(
wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)),
wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32))
);
auto print_func1 = wasm::Func::make(store, print_type1.get(), print_callback);

auto print_type2 = wasm::FuncType::make(
wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32), wasm::ValType::make(wasm::I32)),
wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32))
);
auto print_func2 = wasm::Func::make(store, print_type2.get(), print_callback);
auto print_func = wasm::Func::make(store, print_type.get(), print_callback);

// Creating closure.
std::cout << "Creating closure..." << std::endl;
Expand All @@ -109,9 +103,7 @@ void run() {

// Instantiate.
std::cout << "Instantiating module..." << std::endl;
auto imports = wasm::vec<wasm::Extern*>::make(
print_func1, print_func2, closure_func
);
wasm::Extern* imports[] = {print_func.get(), closure_func.get()};
auto instance = wasm::Instance::make(store, module.get(), imports);
if (!instance) {
std::cout << "> Error instantiating module!" << std::endl;
Expand All @@ -129,15 +121,16 @@ void run() {

// Call.
std::cout << "Calling export..." << std::endl;
auto result = run_func->call(wasm::Val::i32(3), wasm::Val::i32(4));
if (result.kind() != wasm::Result::RETURN) {
wasm::Val args[] = {wasm::Val::i32(3), wasm::Val::i32(4)};
wasm::Val results[1];
if (run_func->call(args, results)) {
std::cout << "> Error calling function!" << std::endl;
return;
}

// Print result.
std::cout << "Printing result..." << std::endl;
std::cout << "> " << result[0].i32() << std::endl;
std::cout << "> " << results[0].i32() << std::endl;

// Shut down.
std::cout << "Shutting down..." << std::endl;
Expand Down
Binary file modified example/callback.wasm
Binary file not shown.
8 changes: 2 additions & 6 deletions example/callback.wat
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
(module
(func $print1 (import "" "print1") (param i32) (result i32))
(func $print2 (import "" "print2") (param i32 i32) (result i32))
(func $print (import "" "print") (param i32) (result i32))
(func $closure (import "" "closure") (result i32))
(func (export "run") (param $x i32) (param $y i32) (result i32)
(i32.add
(i32.add
(call $print2 (get_local $x) (get_local $y))
(call $print1 (i32.add (get_local $x) (get_local $y)))
)
(call $print (i32.add (get_local $x) (get_local $y)))
(call $closure)
)
)
Expand Down
38 changes: 13 additions & 25 deletions example/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {

#define check_call(func, type, expected) \
{ \
wasm_val_vec_t args = {0, NULL}; \
wasm_result_t result; \
wasm_func_call(func, &args, &result); \
check(result.of.vals.data[0], type, expected); \
wasm_result_delete(&result); \
wasm_val_t results[1]; \
wasm_func_call(func, NULL, results); \
check(results[0], type, expected); \
}


Expand Down Expand Up @@ -115,14 +113,13 @@ int main(int argc, const char* argv[]) {

// Instantiate.
printf("Instantiating module...\n");
wasm_extern_t* externs[] = {
const wasm_extern_t* imports[] = {
wasm_global_as_extern(const_f32_import),
wasm_global_as_extern(const_i64_import),
wasm_global_as_extern(var_f32_import),
wasm_global_as_extern(var_i64_import)
};
wasm_extern_vec_t imports = {4, externs};
own wasm_instance_t* instance = wasm_instance_new(store, module, &imports);
own wasm_instance_t* instance = wasm_instance_new(store, module, imports);
if (!instance) {
printf("> Error instantiating module!\n");
return 1;
Expand Down Expand Up @@ -195,23 +192,14 @@ int main(int argc, const char* argv[]) {
check_call(get_var_i64_export, f64, f64_reinterpret_i64(38));

// Modify variables through calls and check again.
wasm_result_t result;
wasm_val_t val73 = {.kind = WASM_F32, .of = {.f32 = 73}};
wasm_val_vec_t args73 = { 1, &val73 };
wasm_func_call(set_var_f32_import, &args73, &result);
wasm_result_delete(&result);
wasm_val_t val74 = {.kind = WASM_F64, .of = {.f64 = f64_reinterpret_i64(74)}};
wasm_val_vec_t args74 = { 1, &val74 };
wasm_func_call(set_var_i64_import, &args74, &result);
wasm_result_delete(&result);
wasm_val_t val77 = {.kind = WASM_F32, .of = {.f32 = 77}};
wasm_val_vec_t args77 = { 1, &val77 };
wasm_func_call(set_var_f32_export, &args77, &result);
wasm_result_delete(&result);
wasm_val_t val78 = {.kind = WASM_F64, .of = {.f64 = f64_reinterpret_i64(78)}};
wasm_val_vec_t args78 = { 1, &val78 };
wasm_func_call(set_var_i64_export, &args78, &result);
wasm_result_delete(&result);
wasm_val_t args73[] = { {.kind = WASM_F32, .of = {.f32 = 73}} };
wasm_func_call(set_var_f32_import, args73, NULL);
wasm_val_t args74[] = { {.kind = WASM_F64, .of = {.f64 = f64_reinterpret_i64(74)}} };
wasm_func_call(set_var_i64_import, args74, NULL);
wasm_val_t args77[] = { {.kind = WASM_F32, .of = {.f32 = 77}} };
wasm_func_call(set_var_f32_export, args77, NULL);
wasm_val_t args78[] = { {.kind = WASM_F64, .of = {.f64 = f64_reinterpret_i64(78)}} };
wasm_func_call(set_var_i64_export, args78, NULL);

check_global(var_f32_import, f32, 73);
check_global(var_i64_import, i64, 74);
Expand Down
66 changes: 42 additions & 24 deletions example/global.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ void check(T actual, U expected) {
}
}

auto call(const wasm::Func* func) -> wasm::Val {
wasm::Val results[1];
if (func->call(nullptr, results)) {
std::cout << "> Error calling function!" << std::endl;
exit(1);
}
return results[0].copy();
}

void call(const wasm::Func* func, wasm::Val&& arg) {
wasm::Val args[1] = {std::move(arg)};
if (func->call(args)) {
std::cout << "> Error calling function!" << std::endl;
exit(1);
}
}


void run() {
// Initialize.
std::cout << "Initializing..." << std::endl;
Expand Down Expand Up @@ -86,10 +104,10 @@ void run() {

// Instantiate.
std::cout << "Instantiating module..." << std::endl;
auto imports = wasm::vec<wasm::Extern*>::make(
const_f32_import->copy(), const_i64_import->copy(),
var_f32_import->copy(), var_i64_import->copy()
);
wasm::Extern* imports[] = {
const_f32_import.get(), const_i64_import.get(),
var_f32_import.get(), var_i64_import.get()
};
auto instance = wasm::Instance::make(store, module.get(), imports);
if (!instance) {
std::cout << "> Error instantiating module!" << std::endl;
Expand Down Expand Up @@ -130,14 +148,14 @@ void run() {
check(var_f32_export->get().f32(), 7);
check(var_i64_export->get().i64(), 8);

check(get_const_f32_import->call()[0].f32(), 1);
check(get_const_i64_import->call()[0].f64(), f64_reinterpret_i64(2));
check(get_var_f32_import->call()[0].f32(), 3);
check(get_var_i64_import->call()[0].f64(), f64_reinterpret_i64(4));
check(get_const_f32_export->call()[0].f32(), 5);
check(get_const_i64_export->call()[0].f64(), f64_reinterpret_i64(6));
check(get_var_f32_export->call()[0].f32(), 7);
check(get_var_i64_export->call()[0].f64(), f64_reinterpret_i64(8));
check(call(get_const_f32_import).f32(), 1);
check(call(get_const_i64_import).f64(), f64_reinterpret_i64(2));
check(call(get_var_f32_import).f32(), 3);
check(call(get_var_i64_import).f64(), f64_reinterpret_i64(4));
check(call(get_const_f32_export).f32(), 5);
check(call(get_const_i64_export).f64(), f64_reinterpret_i64(6));
check(call(get_var_f32_export).f32(), 7);
check(call(get_var_i64_export).f64(), f64_reinterpret_i64(8));

// Modify variables through API and check again.
var_f32_import->set(wasm::Val::f32(33));
Expand All @@ -150,26 +168,26 @@ void run() {
check(var_f32_export->get().f32(), 37);
check(var_i64_export->get().i64(), 38);

check(get_var_f32_import->call()[0].f32(), 33);
check(get_var_i64_import->call()[0].f64(), f64_reinterpret_i64(34));
check(get_var_f32_export->call()[0].f32(), 37);
check(get_var_i64_export->call()[0].f64(), f64_reinterpret_i64(38));
check(call(get_var_f32_import).f32(), 33);
check(call(get_var_i64_import).f64(), f64_reinterpret_i64(34));
check(call(get_var_f32_export).f32(), 37);
check(call(get_var_i64_export).f64(), f64_reinterpret_i64(38));

// Modify variables through calls and check again.
set_var_f32_import->call(wasm::Val::f32(73));
set_var_i64_import->call(wasm::Val::f64(f64_reinterpret_i64(74)));
set_var_f32_export->call(wasm::Val::f32(77));
set_var_i64_export->call(wasm::Val::f64(f64_reinterpret_i64(78)));
call(set_var_f32_import, wasm::Val::f32(73));
call(set_var_i64_import, wasm::Val::f64(f64_reinterpret_i64(74)));
call(set_var_f32_export, wasm::Val::f32(77));
call(set_var_i64_export, wasm::Val::f64(f64_reinterpret_i64(78)));

check(var_f32_import->get().f32(), 73);
check(var_i64_import->get().i64(), 74);
check(var_f32_export->get().f32(), 77);
check(var_i64_export->get().i64(), 78);

check(get_var_f32_import->call()[0].f32(), 73);
check(get_var_i64_import->call()[0].f64(), f64_reinterpret_i64(74));
check(get_var_f32_export->call()[0].f32(), 77);
check(get_var_i64_export->call()[0].f64(), f64_reinterpret_i64(78));
check(call(get_var_f32_import).f32(), 73);
check(call(get_var_i64_import).f64(), f64_reinterpret_i64(74));
check(call(get_var_f32_export).f32(), 77);
check(call(get_var_i64_export).f64(), f64_reinterpret_i64(78));

// Shut down.
std::cout << "Shutting down..." << std::endl;
Expand Down
Loading