From fbc6ab575225ffa565b4e255b9df355f64b529ca Mon Sep 17 00:00:00 2001 From: Andrew Scheidecker Date: Fri, 1 Nov 2019 07:24:29 -0400 Subject: [PATCH] Add a Chromium .clang-format file, and apply it --- .clang-format | 1 + example/callback.c | 33 +- example/callback.cc | 36 +- example/finalize.c | 10 +- example/finalize.cc | 13 +- example/global.c | 68 +-- example/global.cc | 55 +- example/hello.c | 13 +- example/hello.cc | 23 +- example/hostref.c | 42 +- example/hostref.cc | 54 +- example/memory.c | 38 +- example/memory.cc | 29 +- example/multi.c | 34 +- example/multi.cc | 34 +- example/reflect.c | 49 +- example/reflect.cc | 55 +- example/serialize.c | 9 +- example/serialize.cc | 23 +- example/start.c | 16 +- example/start.cc | 10 +- example/table.c | 44 +- example/table.cc | 51 +- example/threads.c | 17 +- example/threads.cc | 36 +- example/trap.c | 27 +- example/trap.cc | 28 +- include/wasm.h | 279 +++++---- include/wasm.hh | 324 ++++++----- src/wasm-bin.cc | 270 +++++---- src/wasm-c.cc | 735 ++++++++++++----------- src/wasm-v8-lowlevel.cc | 434 ++++++++------ src/wasm-v8-lowlevel.hh | 14 +- src/wasm-v8.cc | 1218 +++++++++++++++++++++------------------ 34 files changed, 2173 insertions(+), 1949 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..34fe704 --- /dev/null +++ b/.clang-format @@ -0,0 +1 @@ +BasedOnStyle: Chromium \ No newline at end of file diff --git a/example/callback.c b/example/callback.c index e17429b..04c297f 100644 --- a/example/callback.c +++ b/example/callback.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "wasm.h" @@ -34,9 +34,7 @@ void wasm_val_print(wasm_val_t val) { } // A function to be called from Wasm code. -own wasm_trap_t* print_callback( - const wasm_val_t args[], wasm_val_t results[] -) { +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"); @@ -45,11 +43,10 @@ own wasm_trap_t* print_callback( return NULL; } - // A function closure. -own wasm_trap_t* closure_callback( - void* env, const wasm_val_t args[], wasm_val_t results[] -) { +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); @@ -59,7 +56,6 @@ own wasm_trap_t* closure_callback( return NULL; } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -96,23 +92,26 @@ int main(int argc, const char* argv[]) { // Create external print functions. 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); + 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); + 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_type); wasm_functype_delete(closure_type); // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { - wasm_func_as_extern(print_func), wasm_func_as_extern(closure_func) - }; + const wasm_extern_t* imports[] = {wasm_func_as_extern(print_func), + wasm_func_as_extern(closure_func)}; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/example/callback.cc b/example/callback.cc index d9f8751..a18569c 100644 --- a/example/callback.cc +++ b/example/callback.cc @@ -1,8 +1,8 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" @@ -34,19 +34,16 @@ auto operator<<(std::ostream& out, const wasm::Val& val) -> std::ostream& { } // A function to be called from Wasm code. -auto print_callback( - const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto print_callback(const wasm::Val args[], wasm::Val results[]) + -> wasm::own { 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::Val args[], wasm::Val results[] -) -> wasm::own { +auto closure_callback(void* env, const wasm::Val args[], wasm::Val results[]) + -> wasm::own { auto i = *reinterpret_cast(env); std::cout << "Calling back closure..." << std::endl; std::cout << "> " << i << std::endl; @@ -54,7 +51,6 @@ auto closure_callback( return nullptr; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -87,19 +83,18 @@ void run() { // Create external print functions. std::cout << "Creating callback..." << std::endl; auto print_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::I32)), - wasm::ownvec::make(wasm::ValType::make(wasm::I32)) - ); + wasm::ownvec::make(wasm::ValType::make(wasm::I32)), + wasm::ownvec::make(wasm::ValType::make(wasm::I32))); auto print_func = wasm::Func::make(store, print_type.get(), print_callback); // Creating closure. std::cout << "Creating closure..." << std::endl; int i = 42; auto closure_type = wasm::FuncType::make( - wasm::ownvec::make(), - wasm::ownvec::make(wasm::ValType::make(wasm::I32)) - ); - auto closure_func = wasm::Func::make(store, closure_type.get(), closure_callback, &i); + wasm::ownvec::make(), + wasm::ownvec::make(wasm::ValType::make(wasm::I32))); + auto closure_func = + wasm::Func::make(store, closure_type.get(), closure_callback, &i); // Instantiate. std::cout << "Instantiating module..." << std::endl; @@ -113,7 +108,8 @@ void run() { // Extract export. std::cout << "Extracting export..." << std::endl; auto exports = instance->exports(); - if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { + if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || + !exports[0]->func()) { std::cout << "> Error accessing export!" << std::endl; exit(1); } @@ -136,10 +132,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/finalize.c b/example/finalize.c index 247368f..402f7e8 100644 --- a/example/finalize.c +++ b/example/finalize.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "wasm.h" @@ -13,7 +13,8 @@ int live_count = 0; void finalize(void* data) { int i = (int)data; - if (i % (iterations / 10) == 0) printf("Finalizing #%d...\n", i); + if (i % (iterations / 10) == 0) + printf("Finalizing #%d...\n", i); --live_count; } @@ -49,9 +50,10 @@ void run_in_store(wasm_store_t* store) { // Instantiate. printf("Instantiating modules...\n"); for (int i = 0; i <= iterations; ++i) { - if (i % (iterations / 10) == 0) printf("%d\n", i); + if (i % (iterations / 10) == 0) + printf("%d\n", i); own wasm_instance_t* instance = - wasm_instance_new(store, module, NULL, NULL); + wasm_instance_new(store, module, NULL, NULL); if (!instance) { printf("> Error instantiating module %d!\n", i); exit(1); diff --git a/example/finalize.cc b/example/finalize.cc index 64e134b..c96bebf 100644 --- a/example/finalize.cc +++ b/example/finalize.cc @@ -1,12 +1,11 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - const int iterations = 100000; int live_count = 0; @@ -45,7 +44,8 @@ void run_in_store(wasm::Store* store) { // Instantiate. std::cout << "Instantiating modules..." << std::endl; for (int i = 0; i <= iterations; ++i) { - if (i % (iterations / 10) == 0) std::cout << i << std::endl; + if (i % (iterations / 10) == 0) + std::cout << i << std::endl; auto instance = wasm::Instance::make(store, module.get(), nullptr); if (!instance) { std::cout << "> Error instantiating module " << i << "!" << std::endl; @@ -59,7 +59,6 @@ void run_in_store(wasm::Store* store) { std::cout << "Shutting down..." << std::endl; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -92,7 +91,6 @@ void run() { std::cout << "Deleting store 1..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Live count " << live_count << std::endl; @@ -100,4 +98,3 @@ int main(int argc, const char* argv[]) { std::cout << "Done." << std::endl; return 0; } - diff --git a/example/global.c b/example/global.c index 5fe357c..4e7d3fa 100644 --- a/example/global.c +++ b/example/global.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "wasm.h" @@ -23,28 +23,26 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { return wasm_extern_as_func(exports->data[i]); } - -#define check(val, type, expected) \ - if (val.of.type != expected) { \ +#define check(val, type, expected) \ + if (val.of.type != expected) { \ printf("> Error reading value\n"); \ - exit(1); \ + exit(1); \ } #define check_global(global, type, expected) \ - { \ - wasm_val_t val; \ - wasm_global_get(global, &val); \ - check(val, type, expected); \ + { \ + wasm_val_t val; \ + wasm_global_get(global, &val); \ + check(val, type, expected); \ } #define check_call(func, type, expected) \ - { \ - wasm_val_t results[1]; \ + { \ + wasm_val_t results[1]; \ wasm_func_call(func, NULL, results); \ - check(results[0], type, expected); \ + check(results[0], type, expected); \ } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -81,27 +79,27 @@ int main(int argc, const char* argv[]) { // Create external globals. printf("Creating globals...\n"); - own wasm_globaltype_t* const_f32_type = wasm_globaltype_new( - wasm_valtype_new(WASM_F32), WASM_CONST); - own wasm_globaltype_t* const_i64_type = wasm_globaltype_new( - wasm_valtype_new(WASM_I64), WASM_CONST); - own wasm_globaltype_t* var_f32_type = wasm_globaltype_new( - wasm_valtype_new(WASM_F32), WASM_VAR); - own wasm_globaltype_t* var_i64_type = wasm_globaltype_new( - wasm_valtype_new(WASM_I64), WASM_VAR); + own wasm_globaltype_t* const_f32_type = + wasm_globaltype_new(wasm_valtype_new(WASM_F32), WASM_CONST); + own wasm_globaltype_t* const_i64_type = + wasm_globaltype_new(wasm_valtype_new(WASM_I64), WASM_CONST); + own wasm_globaltype_t* var_f32_type = + wasm_globaltype_new(wasm_valtype_new(WASM_F32), WASM_VAR); + own wasm_globaltype_t* var_i64_type = + wasm_globaltype_new(wasm_valtype_new(WASM_I64), WASM_VAR); wasm_val_t val_f32_1 = {.kind = WASM_F32, .of = {.f32 = 1}}; own wasm_global_t* const_f32_import = - wasm_global_new(store, const_f32_type, &val_f32_1); + wasm_global_new(store, const_f32_type, &val_f32_1); wasm_val_t val_i64_2 = {.kind = WASM_I64, .of = {.i64 = 2}}; own wasm_global_t* const_i64_import = - wasm_global_new(store, const_i64_type, &val_i64_2); + wasm_global_new(store, const_i64_type, &val_i64_2); wasm_val_t val_f32_3 = {.kind = WASM_F32, .of = {.f32 = 3}}; own wasm_global_t* var_f32_import = - wasm_global_new(store, var_f32_type, &val_f32_3); + wasm_global_new(store, var_f32_type, &val_f32_3); wasm_val_t val_i64_4 = {.kind = WASM_I64, .of = {.i64 = 4}}; own wasm_global_t* var_i64_import = - wasm_global_new(store, var_i64_type, &val_i64_4); + wasm_global_new(store, var_i64_type, &val_i64_4); wasm_globaltype_delete(const_f32_type); wasm_globaltype_delete(const_i64_type); @@ -110,14 +108,12 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - 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) - }; + 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)}; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -195,13 +191,13 @@ int main(int argc, const char* argv[]) { check_call(get_var_i64_export, i64, 38); // Modify variables through calls and check again. - wasm_val_t args73[] = { {.kind = WASM_F32, .of = {.f32 = 73}} }; + 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_I64, .of = {.i64 = 74}} }; + wasm_val_t args74[] = {{.kind = WASM_I64, .of = {.i64 = 74}}}; wasm_func_call(set_var_i64_import, args74, NULL); - wasm_val_t args77[] = { {.kind = WASM_F32, .of = {.f32 = 77}} }; + 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_I64, .of = {.i64 = 78}} }; + wasm_val_t args78[] = {{.kind = WASM_I64, .of = {.i64 = 78}}}; wasm_func_call(set_var_i64_export, args78, NULL); check_global(var_f32_import, f32, 73); diff --git a/example/global.cc b/example/global.cc index 811024e..e14cce8 100644 --- a/example/global.cc +++ b/example/global.cc @@ -1,13 +1,13 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - -auto get_export_global(wasm::ownvec& exports, size_t i) -> wasm::Global* { +auto get_export_global(wasm::ownvec& exports, size_t i) + -> wasm::Global* { if (exports.size() <= i || !exports[i]->global()) { std::cout << "> Error accessing global export " << i << "!" << std::endl; exit(1); @@ -15,7 +15,8 @@ auto get_export_global(wasm::ownvec& exports, size_t i) -> wasm::G return exports[i]->global(); } -auto get_export_func(const wasm::ownvec& exports, size_t i) -> const wasm::Func* { +auto get_export_func(const wasm::ownvec& exports, size_t i) + -> const wasm::Func* { if (exports.size() <= i || !exports[i]->func()) { std::cout << "> Error accessing function export " << i << "!" << std::endl; exit(1); @@ -23,10 +24,11 @@ auto get_export_func(const wasm::ownvec& exports, size_t i) -> con return exports[i]->func(); } -template +template void check(T actual, U expected) { if (actual != expected) { - std::cout << "> Error reading value, expected " << expected << ", got " << actual << std::endl; + std::cout << "> Error reading value, expected " << expected << ", got " + << actual << std::endl; exit(1); } } @@ -48,7 +50,6 @@ void call(const wasm::Func* func, wasm::Val&& arg) { } } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -80,25 +81,27 @@ void run() { // Create external globals. std::cout << "Creating globals..." << std::endl; - auto const_f32_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::F32), wasm::CONST); - auto const_i64_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::I64), wasm::CONST); - auto var_f32_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::F32), wasm::VAR); - auto var_i64_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::I64), wasm::VAR); - auto const_f32_import = wasm::Global::make(store, const_f32_type.get(), wasm::Val::f32(1)); - auto const_i64_import = wasm::Global::make(store, const_i64_type.get(), wasm::Val::i64(2)); - auto var_f32_import = wasm::Global::make(store, var_f32_type.get(), wasm::Val::f32(3)); - auto var_i64_import = wasm::Global::make(store, var_i64_type.get(), wasm::Val::i64(4)); + auto const_f32_type = + wasm::GlobalType::make(wasm::ValType::make(wasm::F32), wasm::CONST); + auto const_i64_type = + wasm::GlobalType::make(wasm::ValType::make(wasm::I64), wasm::CONST); + auto var_f32_type = + wasm::GlobalType::make(wasm::ValType::make(wasm::F32), wasm::VAR); + auto var_i64_type = + wasm::GlobalType::make(wasm::ValType::make(wasm::I64), wasm::VAR); + auto const_f32_import = + wasm::Global::make(store, const_f32_type.get(), wasm::Val::f32(1)); + auto const_i64_import = + wasm::Global::make(store, const_i64_type.get(), wasm::Val::i64(2)); + auto var_f32_import = + wasm::Global::make(store, var_f32_type.get(), wasm::Val::f32(3)); + auto var_i64_import = + wasm::Global::make(store, var_i64_type.get(), wasm::Val::i64(4)); // Instantiate. std::cout << "Instantiating module..." << std::endl; - wasm::Extern* imports[] = { - const_f32_import.get(), const_i64_import.get(), - var_f32_import.get(), var_i64_import.get() - }; + 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; @@ -187,10 +190,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/hello.c b/example/hello.c index e4ef983..138a0cd 100644 --- a/example/hello.c +++ b/example/hello.c @@ -1,22 +1,19 @@ +#include #include #include #include -#include #include "wasm.h" #define own // A function to be called from Wasm code. -own wasm_trap_t* hello_callback( - const wasm_val_t args[], wasm_val_t results[] -) { +own wasm_trap_t* hello_callback(const wasm_val_t args[], wasm_val_t results[]) { printf("Calling back...\n"); printf("> Hello World!\n"); return NULL; } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -55,15 +52,15 @@ int main(int argc, const char* argv[]) { printf("Creating callback...\n"); own wasm_functype_t* hello_type = wasm_functype_new_0_0(); own wasm_func_t* hello_func = - wasm_func_new(store, hello_type, hello_callback); + wasm_func_new(store, hello_type, hello_callback); wasm_functype_delete(hello_type); // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) }; + const wasm_extern_t* imports[] = {wasm_func_as_extern(hello_func)}; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/example/hello.cc b/example/hello.cc index e009b3b..407b907 100644 --- a/example/hello.cc +++ b/example/hello.cc @@ -1,22 +1,19 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - // A function to be called from Wasm code. -auto hello_callback( - const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto hello_callback(const wasm::Val args[], wasm::Val results[]) + -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> Hello world!" << std::endl; return nullptr; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -48,9 +45,8 @@ void run() { // Create external print functions. std::cout << "Creating callback..." << std::endl; - auto hello_type = wasm::FuncType::make( - wasm::ownvec::make(), wasm::ownvec::make() - ); + auto hello_type = wasm::FuncType::make(wasm::ownvec::make(), + wasm::ownvec::make()); auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback); // Instantiate. @@ -65,7 +61,8 @@ void run() { // Extract export. std::cout << "Extracting export..." << std::endl; auto exports = instance->exports(); - if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { + if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || + !exports[0]->func()) { std::cout << "> Error accessing export!" << std::endl; exit(1); } @@ -82,10 +79,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/hostref.c b/example/hostref.c index b70218e..d5dde0b 100644 --- a/example/hostref.c +++ b/example/hostref.c @@ -1,25 +1,21 @@ +#include #include #include #include -#include #include "wasm.h" #define own - // A function to be called from Wasm code. -own wasm_trap_t* callback( - const wasm_val_t args[], wasm_val_t results[] -) { +own wasm_trap_t* callback(const wasm_val_t args[], wasm_val_t results[]) { printf("Calling back...\n> "); printf("> %p\n", - args[0].of.ref ? wasm_ref_get_host_info(args[0].of.ref) : NULL); + args[0].of.ref ? wasm_ref_get_host_info(args[0].of.ref) : NULL); wasm_val_copy(&results[0], &args[0]); return NULL; } - wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) { printf("> Error accessing function export %zu!\n", i); @@ -44,9 +40,9 @@ wasm_table_t* get_export_table(const wasm_extern_vec_t* exports, size_t i) { return wasm_extern_as_table(exports->data[i]); } - own wasm_ref_t* call_v_r(const wasm_func_t* func) { - printf("call_v_r... "); fflush(stdout); + printf("call_v_r... "); + fflush(stdout); wasm_val_t results[1]; if (wasm_func_call(func, NULL, results)) { printf("> Error calling function!\n"); @@ -57,7 +53,8 @@ own wasm_ref_t* call_v_r(const wasm_func_t* func) { } void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) { - printf("call_r_v... "); fflush(stdout); + printf("call_r_v... "); + fflush(stdout); wasm_val_t args[1]; args[0].kind = WASM_ANYREF; args[0].of.ref = ref; @@ -69,7 +66,8 @@ void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) { } own wasm_ref_t* call_r_r(const wasm_func_t* func, wasm_ref_t* ref) { - printf("call_r_r... "); fflush(stdout); + printf("call_r_r... "); + fflush(stdout); wasm_val_t args[1]; args[0].kind = WASM_ANYREF; args[0].of.ref = ref; @@ -83,7 +81,8 @@ own wasm_ref_t* call_r_r(const wasm_func_t* func, wasm_ref_t* ref) { } void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) { - printf("call_ir_v... "); fflush(stdout); + printf("call_ir_v... "); + fflush(stdout); wasm_val_t args[2]; args[0].kind = WASM_I32; args[0].of.i32 = i; @@ -97,7 +96,8 @@ void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) { } own wasm_ref_t* call_i_r(const wasm_func_t* func, int32_t i) { - printf("call_i_r... "); fflush(stdout); + printf("call_i_r... "); + fflush(stdout); wasm_val_t args[1]; args[0].kind = WASM_I32; args[0].of.i32 = i; @@ -114,14 +114,14 @@ void check(own wasm_ref_t* actual, const wasm_ref_t* expected) { if (actual != expected && !(actual && expected && wasm_ref_same(actual, expected))) { printf("> Error reading reference, expected %p, got %p\n", - expected ? wasm_ref_get_host_info(expected) : NULL, - actual ? wasm_ref_get_host_info(actual) : NULL); + expected ? wasm_ref_get_host_info(expected) : NULL, + actual ? wasm_ref_get_host_info(actual) : NULL); exit(1); } - if (actual) wasm_ref_delete(actual); + if (actual) + wasm_ref_delete(actual); } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -159,17 +159,17 @@ int main(int argc, const char* argv[]) { // Create external callback function. printf("Creating callback...\n"); own wasm_functype_t* callback_type = wasm_functype_new_1_1( - wasm_valtype_new(WASM_ANYREF), wasm_valtype_new(WASM_ANYREF)); + wasm_valtype_new(WASM_ANYREF), wasm_valtype_new(WASM_ANYREF)); own wasm_func_t* callback_func = - wasm_func_new(store, callback_type, callback); + wasm_func_new(store, callback_type, callback); wasm_functype_delete(callback_type); // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(callback_func) }; + const wasm_extern_t* imports[] = {wasm_func_as_extern(callback_func)}; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/example/hostref.cc b/example/hostref.cc index 74e1f11..b16bae8 100644 --- a/example/hostref.cc +++ b/example/hostref.cc @@ -1,32 +1,34 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - // A function to be called from Wasm code. -auto callback( - const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto callback(const wasm::Val args[], wasm::Val results[]) + -> wasm::own { std::cout << "Calling back..." << std::endl; - std::cout << "> " << (args[0].ref() ? args[0].ref()->get_host_info() : nullptr) << std::endl; + std::cout << "> " + << (args[0].ref() ? args[0].ref()->get_host_info() : nullptr) + << std::endl; results[0] = args[0].copy(); return nullptr; } - -auto get_export_func(const wasm::ownvec& exports, size_t i) -> const wasm::Func* { +auto get_export_func(const wasm::ownvec& exports, size_t i) + -> const wasm::Func* { if (exports.size() <= i || !exports[i]->func()) { - std::cout << "> Error accessing function export " << i << "/" << exports.size() << "!" << std::endl; + std::cout << "> Error accessing function export " << i << "/" + << exports.size() << "!" << std::endl; exit(1); } return exports[i]->func(); } -auto get_export_global(wasm::ownvec& exports, size_t i) -> wasm::Global* { +auto get_export_global(wasm::ownvec& exports, size_t i) + -> wasm::Global* { if (exports.size() <= i || !exports[i]->global()) { std::cout << "> Error accessing global export " << i << "!" << std::endl; exit(1); @@ -34,7 +36,8 @@ auto get_export_global(wasm::ownvec& exports, size_t i) -> wasm::G return exports[i]->global(); } -auto get_export_table(wasm::ownvec& exports, size_t i) -> wasm::Table* { +auto get_export_table(wasm::ownvec& exports, size_t i) + -> wasm::Table* { if (exports.size() <= i || !exports[i]->table()) { std::cout << "> Error accessing table export " << i << "!" << std::endl; exit(1); @@ -42,10 +45,10 @@ auto get_export_table(wasm::ownvec& exports, size_t i) -> wasm::Ta return exports[i]->table(); } - void call_r_v(const wasm::Func* func, const wasm::Ref* ref) { std::cout << "call_r_v... " << std::flush; - wasm::Val args[1] = {wasm::Val::ref(ref ? ref->copy() : wasm::own())}; + wasm::Val args[1] = { + wasm::Val::ref(ref ? ref->copy() : wasm::own())}; if (func->call(args, nullptr)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -64,9 +67,11 @@ auto call_v_r(const wasm::Func* func) -> wasm::own { return results[0].release_ref(); } -auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) -> wasm::own { +auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) + -> wasm::own { std::cout << "call_r_r... " << std::flush; - wasm::Val args[1] = {wasm::Val::ref(ref ? ref->copy() : wasm::own())}; + wasm::Val args[1] = { + wasm::Val::ref(ref ? ref->copy() : wasm::own())}; wasm::Val results[1]; if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; @@ -78,7 +83,9 @@ auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) -> wasm::owncopy() : wasm::own())}; + wasm::Val args[2] = { + wasm::Val::i32(i), + wasm::Val::ref(ref ? ref->copy() : wasm::own())}; if (func->call(args, nullptr)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -102,8 +109,8 @@ void check(wasm::own actual, const wasm::Ref* expected) { if (actual.get() != expected && !(actual && expected && actual->same(expected))) { std::cout << "> Error reading reference, expected " - << (expected ? expected->get_host_info() : nullptr) << ", got " - << (actual ? actual->get_host_info() : nullptr) << std::endl; + << (expected ? expected->get_host_info() : nullptr) << ", got " + << (actual ? actual->get_host_info() : nullptr) << std::endl; exit(1); } } @@ -140,9 +147,8 @@ void run() { // Create external callback function. std::cout << "Creating callback..." << std::endl; auto callback_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::ANYREF)), - wasm::ownvec::make(wasm::ValType::make(wasm::ANYREF)) - ); + wasm::ownvec::make(wasm::ValType::make(wasm::ANYREF)), + wasm::ownvec::make(wasm::ValType::make(wasm::ANYREF))); auto callback_func = wasm::Func::make(store, callback_type.get(), callback); // Instantiate. @@ -223,10 +229,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/memory.c b/example/memory.c index af2b941..1019388 100644 --- a/example/memory.c +++ b/example/memory.c @@ -1,13 +1,12 @@ +#include #include #include #include -#include #include "wasm.h" #define own - wasm_memory_t* get_export_memory(const wasm_extern_vec_t* exports, size_t i) { if (exports->size <= i || !wasm_extern_as_memory(exports->data[i])) { printf("> Error accessing memory export %zu!\n", i); @@ -24,7 +23,6 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { return wasm_extern_as_func(exports->data[i]); } - void check(bool success) { if (!success) { printf("> Error, expected success\n"); @@ -45,15 +43,16 @@ void check_call0(wasm_func_t* func, int32_t expected) { } void check_call1(wasm_func_t* func, int32_t arg, int32_t expected) { - wasm_val_t args[] = { {.kind = WASM_I32, .of = {.i32 = arg}} }; + wasm_val_t args[] = {{.kind = WASM_I32, .of = {.i32 = arg}}}; check_call(func, args, expected); } -void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; +void check_call2(wasm_func_t* func, + int32_t arg1, + int32_t arg2, + int32_t expected) { + wasm_val_t args[2] = {{.kind = WASM_I32, .of = {.i32 = arg1}}, + {.kind = WASM_I32, .of = {.i32 = arg2}}}; check_call(func, args, expected); } @@ -65,17 +64,15 @@ void check_ok(wasm_func_t* func, wasm_val_t args[]) { } void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; + wasm_val_t args[2] = {{.kind = WASM_I32, .of = {.i32 = arg1}}, + {.kind = WASM_I32, .of = {.i32 = arg2}}}; check_ok(func, args); } void check_trap(wasm_func_t* func, wasm_val_t args[]) { wasm_val_t results[1]; own wasm_trap_t* trap = wasm_func_call(func, args, results); - if (! trap) { + if (!trap) { printf("> Error on result, expected trap\n"); exit(1); } @@ -83,19 +80,16 @@ void check_trap(wasm_func_t* func, wasm_val_t args[]) { } void check_trap1(wasm_func_t* func, int32_t arg) { - wasm_val_t args[1] = { {.kind = WASM_I32, .of = {.i32 = arg}} }; + wasm_val_t args[1] = {{.kind = WASM_I32, .of = {.i32 = arg}}}; check_trap(func, args); } void check_trap2(wasm_func_t* func, int32_t arg1, int32_t arg2) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; + wasm_val_t args[2] = {{.kind = WASM_I32, .of = {.i32 = arg1}}, + {.kind = WASM_I32, .of = {.i32 = arg2}}}; check_trap(func, args); } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -192,7 +186,7 @@ int main(int argc, const char* argv[]) { check_trap1(load_func, 0x30000); check_trap2(store_func, 0x30000, 0); - check(! wasm_memory_grow(memory, 1)); + check(!wasm_memory_grow(memory, 1)); check(wasm_memory_grow(memory, 0)); wasm_extern_vec_delete(&exports); @@ -205,7 +199,7 @@ int main(int argc, const char* argv[]) { own wasm_memorytype_t* memorytype = wasm_memorytype_new(&limits); own wasm_memory_t* memory2 = wasm_memory_new(store, memorytype); check(wasm_memory_size(memory2) == 5); - check(! wasm_memory_grow(memory2, 1)); + check(!wasm_memory_grow(memory2, 1)); check(wasm_memory_grow(memory2, 0)); wasm_memorytype_delete(memorytype); diff --git a/example/memory.cc b/example/memory.cc index 4094acc..0aa5c06 100644 --- a/example/memory.cc +++ b/example/memory.cc @@ -1,13 +1,13 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - -auto get_export_memory(wasm::ownvec& exports, size_t i) -> wasm::Memory* { +auto get_export_memory(wasm::ownvec& exports, size_t i) + -> wasm::Memory* { if (exports.size() <= i || !exports[i]->memory()) { std::cout << "> Error accessing memory export " << i << "!" << std::endl; exit(1); @@ -15,7 +15,8 @@ auto get_export_memory(wasm::ownvec& exports, size_t i) -> wasm::M return exports[i]->memory(); } -auto get_export_func(const wasm::ownvec& exports, size_t i) -> const wasm::Func* { +auto get_export_func(const wasm::ownvec& exports, size_t i) + -> const wasm::Func* { if (exports.size() <= i || !exports[i]->func()) { std::cout << "> Error accessing function export " << i << "!" << std::endl; exit(1); @@ -23,15 +24,16 @@ auto get_export_func(const wasm::ownvec& exports, size_t i) -> con return exports[i]->func(); } -template +template void check(T actual, U expected) { if (actual != expected) { - std::cout << "> Error on result, expected " << expected << ", got " << actual << std::endl; + std::cout << "> Error on result, expected " << expected << ", got " + << actual << std::endl; exit(1); } } -template +template void check_ok(const wasm::Func* func, Args... xs) { wasm::Val args[] = {wasm::Val::i32(xs)...}; if (func->call(args)) { @@ -40,16 +42,16 @@ void check_ok(const wasm::Func* func, Args... xs) { } } -template +template void check_trap(const wasm::Func* func, Args... xs) { wasm::Val args[] = {wasm::Val::i32(xs)...}; - if (! func->call(args)) { + if (!func->call(args)) { std::cout << "> Error on result, expected trap" << std::endl; exit(1); } } -template +template auto call(const wasm::Func* func, Args... xs) -> int32_t { wasm::Val args[] = {wasm::Val::i32(xs)...}; wasm::Val results[1]; @@ -60,7 +62,6 @@ auto call(const wasm::Func* func, Args... xs) -> int32_t { return results[0].i32(); } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -163,10 +164,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/multi.c b/example/multi.c index 3859401..44f9661 100644 --- a/example/multi.c +++ b/example/multi.c @@ -1,19 +1,17 @@ +#include #include #include #include -#include #include "wasm.h" #define own // A function to be called from Wasm code. -own wasm_trap_t* callback( - const wasm_val_t args[], wasm_val_t results[] -) { +own wasm_trap_t* callback(const wasm_val_t args[], wasm_val_t results[]) { printf("Calling back...\n> "); - printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n", - args[0].of.i32, args[1].of.i64, args[2].of.i64, args[3].of.i32); + printf("> %" PRIu32 " %" PRIu64 " %" PRIu64 " %" PRIu32 "\n", args[0].of.i32, + args[1].of.i64, args[2].of.i64, args[3].of.i32); printf("\n"); wasm_val_copy(&results[0], &args[3]); @@ -23,11 +21,10 @@ own wasm_trap_t* callback( return NULL; } - // A function closure. -own wasm_trap_t* closure_callback( - void* env, const wasm_val_t args[], wasm_val_t results[] -) { +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); @@ -37,7 +34,6 @@ own wasm_trap_t* closure_callback( return NULL; } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -74,16 +70,14 @@ int main(int argc, const char* argv[]) { // Create external print functions. printf("Creating callback...\n"); - wasm_valtype_t* types[4] = { - wasm_valtype_new_i32(), wasm_valtype_new_i64(), - wasm_valtype_new_i64(), wasm_valtype_new_i32() - }; + wasm_valtype_t* types[4] = {wasm_valtype_new_i32(), wasm_valtype_new_i64(), + wasm_valtype_new_i64(), wasm_valtype_new_i32()}; own wasm_valtype_vec_t tuple1, tuple2; wasm_valtype_vec_new(&tuple1, 4, types); wasm_valtype_vec_copy(&tuple2, &tuple1); own wasm_functype_t* callback_type = wasm_functype_new(&tuple1, &tuple2); own wasm_func_t* callback_func = - wasm_func_new(store, callback_type, callback); + wasm_func_new(store, callback_type, callback); wasm_functype_delete(callback_type); @@ -91,7 +85,7 @@ int main(int argc, const char* argv[]) { printf("Instantiating module...\n"); const wasm_extern_t* imports[] = {wasm_func_as_extern(callback_func)}; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -137,9 +131,9 @@ int main(int argc, const char* argv[]) { // Print result. printf("Printing result...\n"); - printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n", - results[0].of.i32, results[1].of.i64, - results[2].of.i64, results[3].of.i32); + printf("> %" PRIu32 " %" PRIu64 " %" PRIu64 " %" PRIu32 "\n", + results[0].of.i32, results[1].of.i64, results[2].of.i64, + results[3].of.i32); assert(results[0].of.i32 == 4); assert(results[1].of.i64 == 3); diff --git a/example/multi.cc b/example/multi.cc index 5ed4c9b..2746708 100644 --- a/example/multi.cc +++ b/example/multi.cc @@ -1,15 +1,14 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" // A function to be called from Wasm code. -auto callback( - const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto callback(const wasm::Val args[], wasm::Val results[]) + -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> " << args[0].i32(); std::cout << " " << args[1].i64(); @@ -22,7 +21,6 @@ auto callback( return nullptr; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -55,13 +53,10 @@ void run() { // Create external print functions. std::cout << "Creating callback..." << std::endl; auto tuple = wasm::ownvec::make( - wasm::ValType::make(wasm::I32), - wasm::ValType::make(wasm::I64), - wasm::ValType::make(wasm::I64), - wasm::ValType::make(wasm::I32) - ); + wasm::ValType::make(wasm::I32), wasm::ValType::make(wasm::I64), + wasm::ValType::make(wasm::I64), wasm::ValType::make(wasm::I32)); auto callback_type = - wasm::FuncType::make(tuple.deep_copy(), tuple.deep_copy()); + wasm::FuncType::make(tuple.deep_copy(), tuple.deep_copy()); auto callback_func = wasm::Func::make(store, callback_type.get(), callback); // Instantiate. @@ -76,7 +71,8 @@ void run() { // Extract export. std::cout << "Extracting export..." << std::endl; auto exports = instance->exports(); - if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { + if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || + !exports[0]->func()) { std::cout << "> Error accessing export!" << std::endl; exit(1); } @@ -84,12 +80,12 @@ void run() { // Call. std::cout << "Calling export..." << std::endl; - wasm::Val args[] = { - wasm::Val::i32(1), wasm::Val::i64(2), wasm::Val::i64(3), wasm::Val::i32(4) - }; + wasm::Val args[] = {wasm::Val::i32(1), wasm::Val::i64(2), wasm::Val::i64(3), + wasm::Val::i32(4)}; wasm::Val results[4]; if (wasm::own trap = run_func->call(args, results)) { - std::cout << "> Error calling function! " << trap->message().get() << std::endl; + std::cout << "> Error calling function! " << trap->message().get() + << std::endl; exit(1); } @@ -109,10 +105,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/reflect.c b/example/reflect.c index 15e0165..5d25ded 100644 --- a/example/reflect.c +++ b/example/reflect.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "wasm.h" @@ -9,24 +9,41 @@ void print_mutability(wasm_mutability_t mut) { switch (mut) { - case WASM_VAR: printf("var"); break; - case WASM_CONST: printf("const"); break; + case WASM_VAR: + printf("var"); + break; + case WASM_CONST: + printf("const"); + break; } } void print_limits(const wasm_limits_t* limits) { printf("%ud", limits->min); - if (limits->max < wasm_limits_max_default) printf(" %ud", limits->max); + if (limits->max < wasm_limits_max_default) + printf(" %ud", limits->max); } void print_valtype(const wasm_valtype_t* type) { switch (wasm_valtype_kind(type)) { - case WASM_I32: printf("i32"); break; - case WASM_I64: printf("i64"); break; - case WASM_F32: printf("f32"); break; - case WASM_F64: printf("f64"); break; - case WASM_ANYREF: printf("anyref"); break; - case WASM_FUNCREF: printf("funcref"); break; + case WASM_I32: + printf("i32"); + break; + case WASM_I64: + printf("i64"); + break; + case WASM_F32: + printf("f32"); + break; + case WASM_F64: + printf("f64"); + break; + case WASM_ANYREF: + printf("anyref"); + break; + case WASM_FUNCREF: + printf("funcref"); + break; } } @@ -45,8 +62,7 @@ void print_valtypes(const wasm_valtype_vec_t* types) { void print_externtype(const wasm_externtype_t* type) { switch (wasm_externtype_kind(type)) { case WASM_EXTERN_FUNC: { - const wasm_functype_t* functype = - wasm_externtype_as_functype_const(type); + const wasm_functype_t* functype = wasm_externtype_as_functype_const(type); printf("func "); print_valtypes(wasm_functype_params(functype)); printf(" -> "); @@ -54,7 +70,7 @@ void print_externtype(const wasm_externtype_t* type) { } break; case WASM_EXTERN_GLOBAL: { const wasm_globaltype_t* globaltype = - wasm_externtype_as_globaltype_const(type); + wasm_externtype_as_globaltype_const(type); printf("global "); print_mutability(wasm_globaltype_mutability(globaltype)); printf(" "); @@ -62,7 +78,7 @@ void print_externtype(const wasm_externtype_t* type) { } break; case WASM_EXTERN_TABLE: { const wasm_tabletype_t* tabletype = - wasm_externtype_as_tabletype_const(type); + wasm_externtype_as_tabletype_const(type); printf("table "); print_limits(wasm_tabletype_limits(tabletype)); printf(" "); @@ -70,7 +86,7 @@ void print_externtype(const wasm_externtype_t* type) { } break; case WASM_EXTERN_MEMORY: { const wasm_memorytype_t* memorytype = - wasm_externtype_as_memorytype_const(type); + wasm_externtype_as_memorytype_const(type); printf("memory "); print_limits(wasm_memorytype_limits(memorytype)); } break; @@ -81,7 +97,6 @@ void print_name(const wasm_name_t* name) { printf("\"%.*s\"", (int)name->size, name->data); } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -134,7 +149,7 @@ int main(int argc, const char* argv[]) { for (size_t i = 0; i < exports.size; ++i) { assert(wasm_extern_kind(exports.data[i]) == - wasm_externtype_kind(wasm_exporttype_type(export_types.data[i]))); + wasm_externtype_kind(wasm_exporttype_type(export_types.data[i]))); printf("> export %zu ", i); print_name(wasm_exporttype_name(export_types.data[i])); printf("\n"); diff --git a/example/reflect.cc b/example/reflect.cc index e0f8ba6..bec753b 100644 --- a/example/reflect.cc +++ b/example/reflect.cc @@ -1,39 +1,48 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - auto operator<<(std::ostream& out, wasm::Mutability mut) -> std::ostream& { switch (mut) { - case wasm::VAR: return out << "var"; - case wasm::CONST: return out << "const"; + case wasm::VAR: + return out << "var"; + case wasm::CONST: + return out << "const"; } return out; } auto operator<<(std::ostream& out, wasm::Limits limits) -> std::ostream& { out << limits.min; - if (limits.max < wasm::Limits(0).max) out << " " << limits.max; + if (limits.max < wasm::Limits(0).max) + out << " " << limits.max; return out; } auto operator<<(std::ostream& out, const wasm::ValType& type) -> std::ostream& { switch (type.kind()) { - case wasm::I32: return out << "i32"; - case wasm::I64: return out << "i64"; - case wasm::F32: return out << "f32"; - case wasm::F64: return out << "f64"; - case wasm::ANYREF: return out << "anyref"; - case wasm::FUNCREF: return out << "funcref"; + case wasm::I32: + return out << "i32"; + case wasm::I64: + return out << "i64"; + case wasm::F32: + return out << "f32"; + case wasm::F64: + return out << "f64"; + case wasm::ANYREF: + return out << "anyref"; + case wasm::FUNCREF: + return out << "funcref"; } return out; } -auto operator<<(std::ostream& out, const wasm::ownvec& types) -> std::ostream& { +auto operator<<(std::ostream& out, const wasm::ownvec& types) + -> std::ostream& { bool first = true; for (size_t i = 0; i < types.size(); ++i) { if (first) { @@ -46,16 +55,20 @@ auto operator<<(std::ostream& out, const wasm::ownvec& types) -> return out; } -auto operator<<(std::ostream& out, const wasm::ExternType& type) -> std::ostream& { +auto operator<<(std::ostream& out, const wasm::ExternType& type) + -> std::ostream& { switch (type.kind()) { case wasm::EXTERN_FUNC: { - out << "func " << type.func()->params() << " -> " << type.func()->results(); + out << "func " << type.func()->params() << " -> " + << type.func()->results(); } break; case wasm::EXTERN_GLOBAL: { - out << "global " << type.global()->mutability() << " " << *type.global()->content(); + out << "global " << type.global()->mutability() << " " + << *type.global()->content(); } break; case wasm::EXTERN_TABLE: { - out << "table " << type.table()->limits() << " " << *type.table()->element(); + out << "table " << type.table()->limits() << " " + << *type.table()->element(); } break; case wasm::EXTERN_MEMORY: { out << "memory " << type.memory()->limits(); @@ -69,7 +82,6 @@ auto operator<<(std::ostream& out, const wasm::Name& name) -> std::ostream& { return out; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -115,7 +127,8 @@ void run() { for (size_t i = 0; i < exports.size(); ++i) { assert(exports[i]->kind() == export_types[i]->type()->kind()); - std::cout << "> export " << i << " " << export_types[i]->name() << std::endl; + std::cout << "> export " << i << " " << export_types[i]->name() + << std::endl; std::cout << ">> initial: " << *export_types[i]->type() << std::endl; std::cout << ">> current: " << *exports[i]->type() << std::endl; if (exports[i]->kind() == wasm::EXTERN_FUNC) { @@ -129,10 +142,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/serialize.c b/example/serialize.c index 4522c00..2ab98d1 100644 --- a/example/serialize.c +++ b/example/serialize.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "wasm.h" @@ -14,7 +14,6 @@ own wasm_trap_t* hello_callback(const wasm_val_t args[], wasm_val_t results[]) { return NULL; } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -70,15 +69,15 @@ int main(int argc, const char* argv[]) { printf("Creating callback...\n"); own wasm_functype_t* hello_type = wasm_functype_new_0_0(); own wasm_func_t* hello_func = - wasm_func_new(store, hello_type, hello_callback); + wasm_func_new(store, hello_type, hello_callback); wasm_functype_delete(hello_type); // Instantiate. printf("Instantiating deserialized module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) }; + const wasm_extern_t* imports[] = {wasm_func_as_extern(hello_func)}; own wasm_instance_t* instance = - wasm_instance_new(store, deserialized, imports, NULL); + wasm_instance_new(store, deserialized, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/example/serialize.cc b/example/serialize.cc index 7f74edb..5e20c82 100644 --- a/example/serialize.cc +++ b/example/serialize.cc @@ -1,22 +1,19 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - // A function to be called from Wasm code. -auto hello_callback( - const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto hello_callback(const wasm::Val args[], wasm::Val results[]) + -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> Hello world!" << std::endl; return nullptr; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -60,9 +57,8 @@ void run() { // Create external print functions. std::cout << "Creating callback..." << std::endl; - auto hello_type = wasm::FuncType::make( - wasm::ownvec::make(), wasm::ownvec::make() - ); + auto hello_type = wasm::FuncType::make(wasm::ownvec::make(), + wasm::ownvec::make()); auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback); // Instantiate. @@ -77,7 +73,8 @@ void run() { // Extract export. std::cout << "Extracting export..." << std::endl; auto exports = instance->exports(); - if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { + if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || + !exports[0]->func()) { std::cout << "> Error accessing export!" << std::endl; exit(1); } @@ -94,10 +91,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/start.c b/example/start.c index 42fa317..d0b6552 100644 --- a/example/start.c +++ b/example/start.c @@ -1,23 +1,18 @@ +#include #include #include #include -#include #include "wasm.h" #define own - void print_frame(wasm_frame_t* frame) { - printf("> %p @ 0x%zx = %"PRIu32".0x%zx\n", - wasm_frame_instance(frame), - wasm_frame_module_offset(frame), - wasm_frame_func_index(frame), - wasm_frame_func_offset(frame) - ); + printf("> %p @ 0x%zx = %" PRIu32 ".0x%zx\n", wasm_frame_instance(frame), + wasm_frame_module_offset(frame), wasm_frame_func_index(frame), + wasm_frame_func_offset(frame)); } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -55,8 +50,7 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); own wasm_trap_t* trap = NULL; - own wasm_instance_t* instance = - wasm_instance_new(store, module, NULL, &trap); + own wasm_instance_t* instance = wasm_instance_new(store, module, NULL, &trap); if (instance || !trap) { printf("> Error instantiating module, expected trap!\n"); return 1; diff --git a/example/start.cc b/example/start.cc index 71d6fd2..5439919 100644 --- a/example/start.cc +++ b/example/start.cc @@ -1,12 +1,11 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - void print_frame(const wasm::Frame* frame) { std::cout << "> " << frame->instance(); std::cout << " @ 0x" << std::hex << frame->module_offset(); @@ -14,7 +13,6 @@ void print_frame(const wasm::Frame* frame) { std::cout << ".0x" << std::hex << frame->func_offset() << std::endl; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -79,10 +77,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/example/table.c b/example/table.c index 9b3beeb..66ef315 100644 --- a/example/table.c +++ b/example/table.c @@ -1,23 +1,20 @@ +#include #include #include #include -#include #include "wasm.h" #define own // A function to be called from Wasm code. -own wasm_trap_t* neg_callback( - const wasm_val_t args[], wasm_val_t results[] -) { +own wasm_trap_t* neg_callback(const wasm_val_t args[], wasm_val_t results[]) { printf("Calling back...\n"); results[0].kind = WASM_I32; results[0].of.i32 = -args[0].of.i32; return NULL; } - wasm_table_t* get_export_table(const wasm_extern_vec_t* exports, size_t i) { if (exports->size <= i || !wasm_extern_as_table(exports->data[i])) { printf("> Error accessing table export %zu!\n", i); @@ -34,7 +31,6 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { return wasm_extern_as_func(exports->data[i]); } - void check(bool success) { if (!success) { printf("> Error, expected success\n"); @@ -45,14 +41,16 @@ void check(bool success) { void check_table(wasm_table_t* table, int32_t i, bool expect_set) { own wasm_ref_t* ref = wasm_table_get(table, i); check((ref != NULL) == expect_set); - if (ref) wasm_ref_delete(ref); + if (ref) + wasm_ref_delete(ref); } -void check_call(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; +void check_call(wasm_func_t* func, + int32_t arg1, + int32_t arg2, + int32_t expected) { + wasm_val_t args[2] = {{.kind = WASM_I32, .of = {.i32 = arg1}}, + {.kind = WASM_I32, .of = {.i32 = arg2}}}; wasm_val_t results[1]; if (wasm_func_call(func, args, results) || results[0].of.i32 != expected) { printf("> Error on result\n"); @@ -61,19 +59,16 @@ void check_call(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) } void check_trap(wasm_func_t* func, int32_t arg1, int32_t arg2) { - wasm_val_t args[2] = { - {.kind = WASM_I32, .of = {.i32 = arg1}}, - {.kind = WASM_I32, .of = {.i32 = arg2}} - }; + wasm_val_t args[2] = {{.kind = WASM_I32, .of = {.i32 = arg1}}, + {.kind = WASM_I32, .of = {.i32 = arg2}}}; own wasm_trap_t* trap = wasm_func_call(func, args, NULL); - if (! trap) { + if (!trap) { printf("> Error on result, expected trap\n"); exit(1); } wasm_trap_delete(trap); } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -130,7 +125,8 @@ int main(int argc, const char* argv[]) { // Create external function. printf("Creating callback...\n"); - own wasm_functype_t* neg_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32()); + own wasm_functype_t* neg_type = + wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32()); own wasm_func_t* h = wasm_func_new(store, neg_type, neg_callback); wasm_functype_delete(neg_type); @@ -153,7 +149,7 @@ int main(int argc, const char* argv[]) { printf("Mutating table...\n"); check(wasm_table_set(table, 0, wasm_func_as_ref(g))); check(wasm_table_set(table, 1, NULL)); - check(! wasm_table_set(table, 2, wasm_func_as_ref(f))); + check(!wasm_table_set(table, 2, wasm_func_as_ref(f))); check_table(table, 0, true); check_table(table, 1, false); check_call(call_indirect, 7, 0, 666); @@ -166,7 +162,7 @@ int main(int argc, const char* argv[]) { check(wasm_table_size(table) == 5); check(wasm_table_set(table, 2, wasm_func_as_ref(f))); check(wasm_table_set(table, 3, wasm_func_as_ref(h))); - check(! wasm_table_set(table, 5, NULL)); + check(!wasm_table_set(table, 5, NULL)); check_table(table, 2, true); check_table(table, 3, true); check_table(table, 4, false); @@ -180,7 +176,7 @@ int main(int argc, const char* argv[]) { check_table(table, 5, true); check_table(table, 6, true); - check(! wasm_table_grow(table, 5, NULL)); + check(!wasm_table_grow(table, 5, NULL)); check(wasm_table_grow(table, 3, NULL)); check(wasm_table_grow(table, 0, NULL)); @@ -193,10 +189,10 @@ int main(int argc, const char* argv[]) { printf("Creating stand-alone table...\n"); wasm_limits_t limits = {5, 5}; own wasm_tabletype_t* tabletype = - wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), &limits); + wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), &limits); own wasm_table_t* table2 = wasm_table_new(store, tabletype, NULL); check(wasm_table_size(table2) == 5); - check(! wasm_table_grow(table2, 1, NULL)); + check(!wasm_table_grow(table2, 1, NULL)); check(wasm_table_grow(table2, 0, NULL)); wasm_tabletype_delete(tabletype); diff --git a/example/table.cc b/example/table.cc index b19d377..8d6495c 100644 --- a/example/table.cc +++ b/example/table.cc @@ -1,23 +1,21 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" - // A function to be called from Wasm code. -auto neg_callback( - const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto neg_callback(const wasm::Val args[], wasm::Val results[]) + -> wasm::own { std::cout << "Calling back..." << std::endl; results[0] = wasm::Val(-args[0].i32()); return nullptr; } - -auto get_export_table(wasm::ownvec& exports, size_t i) -> wasm::Table* { +auto get_export_table(wasm::ownvec& exports, size_t i) + -> wasm::Table* { if (exports.size() <= i || !exports[i]->table()) { std::cout << "> Error accessing table export " << i << "!" << std::endl; exit(1); @@ -25,7 +23,8 @@ auto get_export_table(wasm::ownvec& exports, size_t i) -> wasm::Ta return exports[i]->table(); } -auto get_export_func(const wasm::ownvec& exports, size_t i) -> const wasm::Func* { +auto get_export_func(const wasm::ownvec& exports, size_t i) + -> const wasm::Func* { if (exports.size() <= i || !exports[i]->func()) { std::cout << "> Error accessing function export " << i << "!" << std::endl; exit(1); @@ -33,24 +32,24 @@ auto get_export_func(const wasm::ownvec& exports, size_t i) -> con return exports[i]->func(); } -template +template void check(T actual, U expected) { if (actual != expected) { - std::cout << "> Error on result, expected " << expected << ", got " << actual << std::endl; + std::cout << "> Error on result, expected " << expected << ", got " + << actual << std::endl; exit(1); } } void check(bool success) { - if (! success) { + if (!success) { std::cout << "> Error, expected success" << std::endl; exit(1); } } -auto call( - const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2 -) -> wasm::Val { +auto call(const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2) + -> wasm::Val { wasm::Val args[2] = {std::move(arg1), std::move(arg2)}; wasm::Val results[1]; if (func->call(args, results)) { @@ -63,7 +62,7 @@ auto call( void check_trap(const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2) { wasm::Val args[2] = {std::move(arg1), std::move(arg2)}; wasm::Val results[1]; - if (! func->call(args, results)) { + if (!func->call(args, results)) { std::cout << "> Error on result, expected trap" << std::endl; exit(1); } @@ -118,9 +117,8 @@ void run() { // Create external function. std::cout << "Creating callback..." << std::endl; auto neg_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::I32)), - wasm::ownvec::make(wasm::ValType::make(wasm::I32)) - ); + wasm::ownvec::make(wasm::ValType::make(wasm::I32)), + wasm::ownvec::make(wasm::ValType::make(wasm::I32))); auto h = wasm::Func::make(store, neg_type.get(), neg_callback); // Try cloning. @@ -139,7 +137,7 @@ void run() { std::cout << "Mutating table..." << std::endl; check(table->set(0, g)); check(table->set(1, nullptr)); - check(! table->set(2, f)); + check(!table->set(2, f)); check(table->get(0) != nullptr); check(table->get(1) == nullptr); check(call(call_indirect, wasm::Val::i32(7), wasm::Val::i32(0)).i32(), 666); @@ -152,7 +150,7 @@ void run() { check(table->size(), 5u); check(table->set(2, f)); check(table->set(3, h.get())); - check(! table->set(5, nullptr)); + check(!table->set(5, nullptr)); check(table->get(2) != nullptr); check(table->get(3) != nullptr); check(table->get(4) == nullptr); @@ -166,25 +164,24 @@ void run() { check(table->get(5) != nullptr); check(table->get(6) != nullptr); - check(! table->grow(5)); + check(!table->grow(5)); check(table->grow(3)); check(table->grow(0)); // Create stand-alone table. // TODO(wasm+): Once Wasm allows multiple tables, turn this into import. std::cout << "Creating stand-alone table..." << std::endl; - auto tabletype = wasm::TableType::make( - wasm::ValType::make(wasm::FUNCREF), wasm::Limits(5, 5)); + auto tabletype = wasm::TableType::make(wasm::ValType::make(wasm::FUNCREF), + wasm::Limits(5, 5)); auto table2 = wasm::Table::make(store, tabletype.get()); check(table2->size() == 5); - check(! table2->grow(1)); + check(!table2->grow(1)); check(table2->grow(0)); // Shut down. std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; diff --git a/example/threads.c b/example/threads.c index 9f9d589..2149689 100644 --- a/example/threads.c +++ b/example/threads.c @@ -1,8 +1,8 @@ #include +#include #include #include #include -#include #include #include "wasm.h" @@ -19,7 +19,6 @@ own wasm_trap_t* callback(const wasm_val_t args[], wasm_val_t results[]) { return NULL; } - typedef struct { wasm_engine_t* engine; wasm_shared_module_t* module; @@ -38,22 +37,24 @@ void* run(void* args_abs) { usleep(100000); // Create imports. - own wasm_functype_t* func_type = wasm_functype_new_1_0(wasm_valtype_new_i32()); + own wasm_functype_t* func_type = + wasm_functype_new_1_0(wasm_valtype_new_i32()); own wasm_func_t* func = wasm_func_new(store, func_type, callback); wasm_functype_delete(func_type); wasm_val_t val = {.kind = WASM_I32, .of = {.i32 = (int32_t)args->id}}; own wasm_globaltype_t* global_type = - wasm_globaltype_new(wasm_valtype_new_i32(), WASM_CONST); + wasm_globaltype_new(wasm_valtype_new_i32(), WASM_CONST); own wasm_global_t* global = wasm_global_new(store, global_type, &val); wasm_globaltype_delete(global_type); // Instantiate. const wasm_extern_t* imports[] = { - wasm_func_as_extern(func), wasm_global_as_extern(global), + wasm_func_as_extern(func), + wasm_global_as_extern(global), }; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return NULL; @@ -69,7 +70,7 @@ void* run(void* args_abs) { printf("> Error accessing exports!\n"); return NULL; } - const wasm_func_t *run_func = wasm_extern_as_func(exports.data[0]); + const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]); if (run_func == NULL) { printf("> Error accessing export!\n"); return NULL; @@ -94,7 +95,7 @@ void* run(void* args_abs) { return NULL; } -int main(int argc, const char *argv[]) { +int main(int argc, const char* argv[]) { // Initialize. wasm_engine_t* engine = wasm_engine_new(); diff --git a/example/threads.cc b/example/threads.cc index 3fdaded..f21ad6f 100644 --- a/example/threads.cc +++ b/example/threads.cc @@ -1,7 +1,7 @@ -#include #include -#include +#include #include +#include #include "wasm.hh" @@ -9,9 +9,8 @@ const int N_THREADS = 10; const int N_REPS = 3; // A function to be called from Wasm code. -auto callback( - void* env, const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto callback(void* env, const wasm::Val args[], wasm::Val results[]) + -> wasm::own { assert(args[0].kind() == wasm::I32); std::lock_guard(*reinterpret_cast(env)); std::cout << "Thread " << args[0].i32() << " running..." << std::endl; @@ -19,11 +18,10 @@ auto callback( return nullptr; } - -void run( - wasm::Engine* engine, const wasm::Shared* shared, - std::mutex* mutex, int id -) { +void run(wasm::Engine* engine, + const wasm::Shared* shared, + std::mutex* mutex, + int id) { // Create store. auto store_ = wasm::Store::make(engine); auto store = store_.get(); @@ -42,15 +40,14 @@ void run( // Create imports. auto func_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::I32)), - wasm::ownvec::make() - ); + wasm::ownvec::make(wasm::ValType::make(wasm::I32)), + wasm::ownvec::make()); auto func = wasm::Func::make(store, func_type.get(), callback, mutex); - auto global_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::I32), wasm::CONST); - auto global = wasm::Global::make( - store, global_type.get(), wasm::Val::i32(i)); + auto global_type = + wasm::GlobalType::make(wasm::ValType::make(wasm::I32), wasm::CONST); + auto global = + wasm::Global::make(store, global_type.get(), wasm::Val::i32(i)); // Instantiate. wasm::Extern* imports[] = {func.get(), global.get()}; @@ -63,7 +60,8 @@ void run( // Extract export. auto exports = instance->exports(); - if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { + if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || + !exports[0]->func()) { std::lock_guard lock(*mutex); std::cout << "> Error accessing export!" << std::endl; exit(1); @@ -75,7 +73,7 @@ void run( } } -int main(int argc, const char *argv[]) { +int main(int argc, const char* argv[]) { // Initialize. std::cout << "Initializing..." << std::endl; auto engine = wasm::Engine::make(); diff --git a/example/trap.c b/example/trap.c index 975d6f8..f13974e 100644 --- a/example/trap.c +++ b/example/trap.c @@ -1,16 +1,16 @@ +#include #include #include #include -#include #include "wasm.h" #define own // A function to be called from Wasm code. -own wasm_trap_t* fail_callback( - void* env, const wasm_val_t args[], wasm_val_t results[] -) { +own wasm_trap_t* fail_callback(void* env, + const wasm_val_t args[], + wasm_val_t results[]) { printf("Calling back...\n"); own wasm_name_t message; wasm_name_new_from_string(&message, "callback abort"); @@ -19,17 +19,12 @@ own wasm_trap_t* fail_callback( return trap; } - void print_frame(wasm_frame_t* frame) { - printf("> %p @ 0x%zx = %"PRIu32".0x%zx\n", - wasm_frame_instance(frame), - wasm_frame_module_offset(frame), - wasm_frame_func_index(frame), - wasm_frame_func_offset(frame) - ); + printf("> %p @ 0x%zx = %" PRIu32 ".0x%zx\n", wasm_frame_instance(frame), + wasm_frame_module_offset(frame), wasm_frame_func_index(frame), + wasm_frame_func_offset(frame)); } - int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -67,17 +62,17 @@ int main(int argc, const char* argv[]) { // Create external print functions. printf("Creating callback...\n"); own wasm_functype_t* fail_type = - wasm_functype_new_0_1(wasm_valtype_new_i32()); + wasm_functype_new_0_1(wasm_valtype_new_i32()); own wasm_func_t* fail_func = - wasm_func_new_with_env(store, fail_type, fail_callback, store, NULL); + wasm_func_new_with_env(store, fail_type, fail_callback, store, NULL); wasm_functype_delete(fail_type); // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(fail_func) }; + const wasm_extern_t* imports[] = {wasm_func_as_extern(fail_func)}; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/example/trap.cc b/example/trap.cc index 3a7dcc6..7337b71 100644 --- a/example/trap.cc +++ b/example/trap.cc @@ -1,22 +1,20 @@ -#include -#include +#include #include +#include +#include #include -#include #include "wasm.hh" // A function to be called from Wasm code. -auto fail_callback( - void* env, const wasm::Val args[], wasm::Val results[] -) -> wasm::own { +auto fail_callback(void* env, const wasm::Val args[], wasm::Val results[]) + -> wasm::own { std::cout << "Calling back..." << std::endl; auto store = reinterpret_cast(env); auto message = wasm::Name::make(std::string("callback abort")); return wasm::Trap::make(store, message); } - void print_frame(const wasm::Frame* frame) { std::cout << "> " << frame->instance(); std::cout << " @ 0x" << std::hex << frame->module_offset(); @@ -24,7 +22,6 @@ void print_frame(const wasm::Frame* frame) { std::cout << ".0x" << std::hex << frame->func_offset() << std::endl; } - void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -57,11 +54,10 @@ void run() { // Create external print functions. std::cout << "Creating callback..." << std::endl; auto fail_type = wasm::FuncType::make( - wasm::ownvec::make(), - wasm::ownvec::make(wasm::ValType::make(wasm::I32)) - ); + wasm::ownvec::make(), + wasm::ownvec::make(wasm::ValType::make(wasm::I32))); auto fail_func = - wasm::Func::make(store, fail_type.get(), fail_callback, store); + wasm::Func::make(store, fail_type.get(), fail_callback, store); // Instantiate. std::cout << "Instantiating module..." << std::endl; @@ -75,9 +71,9 @@ void run() { // Extract export. std::cout << "Extracting exports..." << std::endl; auto exports = instance->exports(); - if (exports.size() < 2 || - exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func() || - exports[1]->kind() != wasm::EXTERN_FUNC || !exports[1]->func()) { + if (exports.size() < 2 || exports[0]->kind() != wasm::EXTERN_FUNC || + !exports[0]->func() || exports[1]->kind() != wasm::EXTERN_FUNC || + !exports[1]->func()) { std::cout << "> Error accessing exports!" << std::endl; exit(1); } @@ -117,10 +113,8 @@ void run() { std::cout << "Shutting down..." << std::endl; } - int main(int argc, const char* argv[]) { run(); std::cout << "Done." << std::endl; return 0; } - diff --git a/include/wasm.h b/include/wasm.h index 3218635..2ee1099 100644 --- a/include/wasm.h +++ b/include/wasm.h @@ -3,12 +3,11 @@ #ifndef __WASM_H #define __WASM_H +#include +#include #include #include -#include #include -#include - #ifdef __cplusplus extern "C" { @@ -23,7 +22,7 @@ inline void assertions() { static_assert(sizeof(float) == sizeof(uint32_t), "incompatible float type"); static_assert(sizeof(double) == sizeof(uint64_t), "incompatible double type"); static_assert(sizeof(intptr_t) == sizeof(uint32_t) || - sizeof(intptr_t) == sizeof(uint64_t), + sizeof(intptr_t) == sizeof(uint64_t), "incompatible pointer type"); } @@ -31,7 +30,6 @@ typedef char byte_t; typedef float float32_t; typedef double float64_t; - // Ownership #define own @@ -57,32 +55,28 @@ typedef double float64_t; // neither the vector nor its elements should be modified. // TODO: introduce proper `wasm_xxx_const_vec_t`? - -#define WASM_DECLARE_OWN(name) \ +#define WASM_DECLARE_OWN(name) \ typedef struct wasm_##name##_t wasm_##name##_t; \ - \ + \ void wasm_##name##_delete(own wasm_##name##_t*); - // Vectors -#define WASM_DECLARE_VEC(name, ptr_or_none) \ - typedef struct wasm_##name##_vec_t { \ - size_t size; \ - wasm_##name##_t ptr_or_none* data; \ - } wasm_##name##_vec_t; \ - \ - void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \ - void wasm_##name##_vec_new_uninitialized( \ - own wasm_##name##_vec_t* out, size_t); \ - void wasm_##name##_vec_new( \ - own wasm_##name##_vec_t* out, \ - size_t, own wasm_##name##_t ptr_or_none const[]); \ - void wasm_##name##_vec_copy( \ - own wasm_##name##_vec_t* out, const wasm_##name##_vec_t*); \ +#define WASM_DECLARE_VEC(name, ptr_or_none) \ + typedef struct wasm_##name##_vec_t { \ + size_t size; \ + wasm_##name##_t ptr_or_none* data; \ + } wasm_##name##_vec_t; \ + \ + void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \ + void wasm_##name##_vec_new_uninitialized(own wasm_##name##_vec_t* out, \ + size_t); \ + void wasm_##name##_vec_new(own wasm_##name##_vec_t* out, size_t, \ + own wasm_##name##_t ptr_or_none const[]); \ + void wasm_##name##_vec_copy(own wasm_##name##_vec_t* out, \ + const wasm_##name##_vec_t*); \ void wasm_##name##_vec_delete(own wasm_##name##_vec_t*); - // Byte vectors typedef byte_t wasm_byte_t; @@ -97,13 +91,11 @@ typedef wasm_byte_vec_t wasm_name_t; #define wasm_name_copy wasm_byte_vec_copy #define wasm_name_delete wasm_byte_vec_delete -static inline void wasm_name_new_from_string( - own wasm_name_t* out, const char* s -) { +static inline void wasm_name_new_from_string(own wasm_name_t* out, + const char* s) { wasm_name_new(out, strlen(s) + 1, s); } - /////////////////////////////////////////////////////////////////////////////// // Runtime Environment @@ -115,7 +107,6 @@ own wasm_config_t* wasm_config_new(); // Embedders may provide custom functions for manipulating configs. - // Engine WASM_DECLARE_OWN(engine) @@ -123,14 +114,12 @@ WASM_DECLARE_OWN(engine) own wasm_engine_t* wasm_engine_new(); own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*); - // Store WASM_DECLARE_OWN(store) own wasm_store_t* wasm_store_new(wasm_engine_t*); - /////////////////////////////////////////////////////////////////////////////// // Type Representations @@ -149,16 +138,14 @@ typedef struct wasm_limits_t { static const uint32_t wasm_limits_max_default = 0xffffffff; - // Generic #define WASM_DECLARE_TYPE(name) \ - WASM_DECLARE_OWN(name) \ - WASM_DECLARE_VEC(name, *) \ - \ + WASM_DECLARE_OWN(name) \ + WASM_DECLARE_VEC(name, *) \ + \ own wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t*); - // Value Types WASM_DECLARE_TYPE(valtype) @@ -191,40 +178,36 @@ static inline bool wasm_valtype_is_ref(const wasm_valtype_t* t) { return wasm_valkind_is_ref(wasm_valtype_kind(t)); } - // Function Types WASM_DECLARE_TYPE(functype) -own wasm_functype_t* wasm_functype_new( - own wasm_valtype_vec_t* params, own wasm_valtype_vec_t* results); +own wasm_functype_t* wasm_functype_new(own wasm_valtype_vec_t* params, + own wasm_valtype_vec_t* results); const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t*); const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t*); - // Global Types WASM_DECLARE_TYPE(globaltype) -own wasm_globaltype_t* wasm_globaltype_new( - own wasm_valtype_t*, wasm_mutability_t); +own wasm_globaltype_t* wasm_globaltype_new(own wasm_valtype_t*, + wasm_mutability_t); const wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t*); wasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t*); - // Table Types WASM_DECLARE_TYPE(tabletype) -own wasm_tabletype_t* wasm_tabletype_new( - own wasm_valtype_t*, const wasm_limits_t*); +own wasm_tabletype_t* wasm_tabletype_new(own wasm_valtype_t*, + const wasm_limits_t*); const wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t*); const wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t*); - // Memory Types WASM_DECLARE_TYPE(memorytype) @@ -233,7 +216,6 @@ own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*); const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t*); - // Extern Types WASM_DECLARE_TYPE(externtype) @@ -258,40 +240,46 @@ wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t*); wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t*); wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t*); -const wasm_externtype_t* wasm_functype_as_externtype_const(const wasm_functype_t*); -const wasm_externtype_t* wasm_globaltype_as_externtype_const(const wasm_globaltype_t*); -const wasm_externtype_t* wasm_tabletype_as_externtype_const(const wasm_tabletype_t*); -const wasm_externtype_t* wasm_memorytype_as_externtype_const(const wasm_memorytype_t*); - -const wasm_functype_t* wasm_externtype_as_functype_const(const wasm_externtype_t*); -const wasm_globaltype_t* wasm_externtype_as_globaltype_const(const wasm_externtype_t*); -const wasm_tabletype_t* wasm_externtype_as_tabletype_const(const wasm_externtype_t*); -const wasm_memorytype_t* wasm_externtype_as_memorytype_const(const wasm_externtype_t*); - +const wasm_externtype_t* wasm_functype_as_externtype_const( + const wasm_functype_t*); +const wasm_externtype_t* wasm_globaltype_as_externtype_const( + const wasm_globaltype_t*); +const wasm_externtype_t* wasm_tabletype_as_externtype_const( + const wasm_tabletype_t*); +const wasm_externtype_t* wasm_memorytype_as_externtype_const( + const wasm_memorytype_t*); + +const wasm_functype_t* wasm_externtype_as_functype_const( + const wasm_externtype_t*); +const wasm_globaltype_t* wasm_externtype_as_globaltype_const( + const wasm_externtype_t*); +const wasm_tabletype_t* wasm_externtype_as_tabletype_const( + const wasm_externtype_t*); +const wasm_memorytype_t* wasm_externtype_as_memorytype_const( + const wasm_externtype_t*); // Import Types WASM_DECLARE_TYPE(importtype) -own wasm_importtype_t* wasm_importtype_new( - own wasm_name_t* module, own wasm_name_t* name, own wasm_externtype_t*); +own wasm_importtype_t* wasm_importtype_new(own wasm_name_t* module, + own wasm_name_t* name, + own wasm_externtype_t*); const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*); const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*); const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*); - // Export Types WASM_DECLARE_TYPE(exporttype) -own wasm_exporttype_t* wasm_exporttype_new( - own wasm_name_t*, own wasm_externtype_t*); +own wasm_exporttype_t* wasm_exporttype_new(own wasm_name_t*, + own wasm_externtype_t*); const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t*); const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t*); - /////////////////////////////////////////////////////////////////////////////// // Runtime Objects @@ -315,39 +303,37 @@ void wasm_val_copy(own wasm_val_t* out, const wasm_val_t*); WASM_DECLARE_VEC(val, ) - // References -#define WASM_DECLARE_REF_BASE(name) \ - WASM_DECLARE_OWN(name) \ - \ - own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \ +#define WASM_DECLARE_REF_BASE(name) \ + WASM_DECLARE_OWN(name) \ + \ + own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \ bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \ - \ - void* wasm_##name##_get_host_info(const wasm_##name##_t*); \ - void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \ - void wasm_##name##_set_host_info_with_finalizer( \ - wasm_##name##_t*, void*, void (*)(void*)); - -#define WASM_DECLARE_REF(name) \ - WASM_DECLARE_REF_BASE(name) \ - \ - wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \ - wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \ + \ + void* wasm_##name##_get_host_info(const wasm_##name##_t*); \ + void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \ + void wasm_##name##_set_host_info_with_finalizer(wasm_##name##_t*, void*, \ + void (*)(void*)); + +#define WASM_DECLARE_REF(name) \ + WASM_DECLARE_REF_BASE(name) \ + \ + wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \ + wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \ const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \ const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*); -#define WASM_DECLARE_SHARABLE_REF(name) \ - WASM_DECLARE_REF(name) \ - WASM_DECLARE_OWN(shared_##name) \ - \ +#define WASM_DECLARE_SHARABLE_REF(name) \ + WASM_DECLARE_REF(name) \ + WASM_DECLARE_OWN(shared_##name) \ + \ own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \ - own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*); - + own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, \ + const wasm_shared_##name##_t*); WASM_DECLARE_REF_BASE(ref) - // Frames WASM_DECLARE_OWN(frame) @@ -359,7 +345,6 @@ uint32_t wasm_frame_func_index(const wasm_frame_t*); size_t wasm_frame_func_offset(const wasm_frame_t*); size_t wasm_frame_module_offset(const wasm_frame_t*); - // Traps typedef wasm_name_t wasm_message_t; // null terminated @@ -372,20 +357,18 @@ void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out); own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*); void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out); - // Foreign Objects WASM_DECLARE_REF(foreign) own wasm_foreign_t* wasm_foreign_new(wasm_store_t*); - // Modules WASM_DECLARE_SHARABLE_REF(module) -own wasm_module_t* wasm_module_new( - wasm_store_t*, const wasm_byte_vec_t* binary); +own wasm_module_t* wasm_module_new(wasm_store_t*, + const wasm_byte_vec_t* binary); bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary); @@ -393,53 +376,59 @@ void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out); void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_vec_t* out); void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out); -own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*); - +own wasm_module_t* wasm_module_deserialize(wasm_store_t*, + const wasm_byte_vec_t*); // Function Instances WASM_DECLARE_REF(func) -typedef own wasm_trap_t* (*wasm_func_callback_t)( - const wasm_val_t args[], wasm_val_t results[]); +typedef own wasm_trap_t* (*wasm_func_callback_t)(const wasm_val_t args[], + wasm_val_t results[]); typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)( - void* env, const wasm_val_t args[], wasm_val_t results[]); - -own wasm_func_t* wasm_func_new( - wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t); -own wasm_func_t* wasm_func_new_with_env( - wasm_store_t*, const wasm_functype_t* type, wasm_func_callback_with_env_t, - void* env, void (*finalizer)(void*)); + void* env, + const wasm_val_t args[], + wasm_val_t results[]); + +own wasm_func_t* wasm_func_new(wasm_store_t*, + const wasm_functype_t*, + wasm_func_callback_t); +own wasm_func_t* wasm_func_new_with_env(wasm_store_t*, + const wasm_functype_t* type, + wasm_func_callback_with_env_t, + void* env, + void (*finalizer)(void*)); own wasm_functype_t* wasm_func_type(const wasm_func_t*); size_t wasm_func_param_arity(const wasm_func_t*); size_t wasm_func_result_arity(const wasm_func_t*); -own wasm_trap_t* wasm_func_call( - const wasm_func_t*, const wasm_val_t args[], wasm_val_t results[]); - +own wasm_trap_t* wasm_func_call(const wasm_func_t*, + const wasm_val_t args[], + wasm_val_t results[]); // Global Instances WASM_DECLARE_REF(global) -own wasm_global_t* wasm_global_new( - wasm_store_t*, const wasm_globaltype_t*, const wasm_val_t*); +own wasm_global_t* wasm_global_new(wasm_store_t*, + const wasm_globaltype_t*, + const wasm_val_t*); own wasm_globaltype_t* wasm_global_type(const wasm_global_t*); void wasm_global_get(const wasm_global_t*, own wasm_val_t* out); void wasm_global_set(wasm_global_t*, const wasm_val_t*); - // Table Instances WASM_DECLARE_REF(table) typedef uint32_t wasm_table_size_t; -own wasm_table_t* wasm_table_new( - wasm_store_t*, const wasm_tabletype_t*, wasm_ref_t* init); +own wasm_table_t* wasm_table_new(wasm_store_t*, + const wasm_tabletype_t*, + wasm_ref_t* init); own wasm_tabletype_t* wasm_table_type(const wasm_table_t*); @@ -449,7 +438,6 @@ bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*); wasm_table_size_t wasm_table_size(const wasm_table_t*); bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init); - // Memory Instances WASM_DECLARE_REF(memory) @@ -468,7 +456,6 @@ size_t wasm_memory_data_size(const wasm_memory_t*); wasm_memory_pages_t wasm_memory_size(const wasm_memory_t*); bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta); - // Externals WASM_DECLARE_REF(extern) @@ -497,19 +484,17 @@ const wasm_global_t* wasm_extern_as_global_const(const wasm_extern_t*); const wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t*); const wasm_memory_t* wasm_extern_as_memory_const(const wasm_extern_t*); - // Module Instances WASM_DECLARE_REF(instance) -own wasm_instance_t* wasm_instance_new( - wasm_store_t*, const wasm_module_t*, const wasm_extern_t* const imports[], - own wasm_trap_t** -); +own wasm_instance_t* wasm_instance_new(wasm_store_t*, + const wasm_module_t*, + const wasm_extern_t* const imports[], + own wasm_trap_t**); void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out); - /////////////////////////////////////////////////////////////////////////////// // Convenience @@ -535,7 +520,6 @@ static inline own wasm_valtype_t* wasm_valtype_new_funcref() { return wasm_valtype_new(WASM_FUNCREF); } - // Function Types construction short-hands static inline own wasm_functype_t* wasm_functype_new_0_0() { @@ -546,8 +530,7 @@ static inline own wasm_functype_t* wasm_functype_new_0_0() { } static inline own wasm_functype_t* wasm_functype_new_1_0( - own wasm_valtype_t* p -) { + own wasm_valtype_t* p) { wasm_valtype_t* ps[1] = {p}; wasm_valtype_vec_t params, results; wasm_valtype_vec_new(¶ms, 1, ps); @@ -556,8 +539,8 @@ static inline own wasm_functype_t* wasm_functype_new_1_0( } static inline own wasm_functype_t* wasm_functype_new_2_0( - own wasm_valtype_t* p1, own wasm_valtype_t* p2 -) { + own wasm_valtype_t* p1, + own wasm_valtype_t* p2) { wasm_valtype_t* ps[2] = {p1, p2}; wasm_valtype_vec_t params, results; wasm_valtype_vec_new(¶ms, 2, ps); @@ -566,8 +549,9 @@ static inline own wasm_functype_t* wasm_functype_new_2_0( } static inline own wasm_functype_t* wasm_functype_new_3_0( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3 -) { + own wasm_valtype_t* p1, + own wasm_valtype_t* p2, + own wasm_valtype_t* p3) { wasm_valtype_t* ps[3] = {p1, p2, p3}; wasm_valtype_vec_t params, results; wasm_valtype_vec_new(¶ms, 3, ps); @@ -576,8 +560,7 @@ static inline own wasm_functype_t* wasm_functype_new_3_0( } static inline own wasm_functype_t* wasm_functype_new_0_1( - own wasm_valtype_t* r -) { + own wasm_valtype_t* r) { wasm_valtype_t* rs[1] = {r}; wasm_valtype_vec_t params, results; wasm_valtype_vec_new_empty(¶ms); @@ -586,8 +569,8 @@ static inline own wasm_functype_t* wasm_functype_new_0_1( } static inline own wasm_functype_t* wasm_functype_new_1_1( - own wasm_valtype_t* p, own wasm_valtype_t* r -) { + own wasm_valtype_t* p, + own wasm_valtype_t* r) { wasm_valtype_t* ps[1] = {p}; wasm_valtype_t* rs[1] = {r}; wasm_valtype_vec_t params, results; @@ -597,8 +580,9 @@ static inline own wasm_functype_t* wasm_functype_new_1_1( } static inline own wasm_functype_t* wasm_functype_new_2_1( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* r -) { + own wasm_valtype_t* p1, + own wasm_valtype_t* p2, + own wasm_valtype_t* r) { wasm_valtype_t* ps[2] = {p1, p2}; wasm_valtype_t* rs[1] = {r}; wasm_valtype_vec_t params, results; @@ -608,9 +592,10 @@ static inline own wasm_functype_t* wasm_functype_new_2_1( } static inline own wasm_functype_t* wasm_functype_new_3_1( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3, - own wasm_valtype_t* r -) { + own wasm_valtype_t* p1, + own wasm_valtype_t* p2, + own wasm_valtype_t* p3, + own wasm_valtype_t* r) { wasm_valtype_t* ps[3] = {p1, p2, p3}; wasm_valtype_t* rs[1] = {r}; wasm_valtype_vec_t params, results; @@ -620,8 +605,8 @@ static inline own wasm_functype_t* wasm_functype_new_3_1( } static inline own wasm_functype_t* wasm_functype_new_0_2( - own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { + own wasm_valtype_t* r1, + own wasm_valtype_t* r2) { wasm_valtype_t* rs[2] = {r1, r2}; wasm_valtype_vec_t params, results; wasm_valtype_vec_new_empty(¶ms); @@ -630,8 +615,9 @@ static inline own wasm_functype_t* wasm_functype_new_0_2( } static inline own wasm_functype_t* wasm_functype_new_1_2( - own wasm_valtype_t* p, own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { + own wasm_valtype_t* p, + own wasm_valtype_t* r1, + own wasm_valtype_t* r2) { wasm_valtype_t* ps[1] = {p}; wasm_valtype_t* rs[2] = {r1, r2}; wasm_valtype_vec_t params, results; @@ -641,9 +627,10 @@ static inline own wasm_functype_t* wasm_functype_new_1_2( } static inline own wasm_functype_t* wasm_functype_new_2_2( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, - own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { + own wasm_valtype_t* p1, + own wasm_valtype_t* p2, + own wasm_valtype_t* r1, + own wasm_valtype_t* r2) { wasm_valtype_t* ps[2] = {p1, p2}; wasm_valtype_t* rs[2] = {r1, r2}; wasm_valtype_vec_t params, results; @@ -653,9 +640,11 @@ static inline own wasm_functype_t* wasm_functype_new_2_2( } static inline own wasm_functype_t* wasm_functype_new_3_2( - own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3, - own wasm_valtype_t* r1, own wasm_valtype_t* r2 -) { + own wasm_valtype_t* p1, + own wasm_valtype_t* p2, + own wasm_valtype_t* p3, + own wasm_valtype_t* r1, + own wasm_valtype_t* r2) { wasm_valtype_t* ps[3] = {p1, p2, p3}; wasm_valtype_t* rs[2] = {r1, r2}; wasm_valtype_vec_t params, results; @@ -664,7 +653,6 @@ static inline own wasm_functype_t* wasm_functype_new_3_2( return wasm_functype_new(¶ms, &results); } - // Value construction short-hands static inline void wasm_val_init_ptr(own wasm_val_t* out, void* p) { @@ -685,7 +673,6 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) { #endif } - /////////////////////////////////////////////////////////////////////////////// #undef own diff --git a/include/wasm.hh b/include/wasm.hh index 8e83345..33a034d 100644 --- a/include/wasm.hh +++ b/include/wasm.hh @@ -7,11 +7,10 @@ #include #include #include -#include #include +#include #include - /////////////////////////////////////////////////////////////////////////////// // Auxiliaries @@ -20,18 +19,18 @@ static_assert(sizeof(float) == sizeof(int32_t), "incompatible float type"); static_assert(sizeof(double) == sizeof(int64_t), "incompatible double type"); static_assert(sizeof(intptr_t) == sizeof(int32_t) || - sizeof(intptr_t) == sizeof(int64_t), "incompatible pointer type"); + sizeof(intptr_t) == sizeof(int64_t), + "incompatible pointer type"); using byte_t = char; using float32_t = float; using float64_t = double; - namespace wasm { // Vectors -template +template class vec { static const size_t invalid_size = SIZE_MAX; @@ -46,7 +45,7 @@ class vec { void free_data() {} #endif - vec(size_t size) : vec(size, size ? new(std::nothrow) T[size] : nullptr) { + vec(size_t size) : vec(size, size ? new (std::nothrow) T[size] : nullptr) { make_data(); } @@ -54,32 +53,22 @@ class vec { assert(!!size_ == !!data_ || size_ == invalid_size); } -public: + public: using elem_type = T; vec(vec&& that) : vec(that.size_, that.data_.release()) { that.size_ = invalid_size; } - ~vec() { - free_data(); - } + ~vec() { free_data(); } - operator bool() const { - return bool(size_ != invalid_size); - } + operator bool() const { return bool(size_ != invalid_size); } - auto size() const -> size_t { - return size_; - } + auto size() const -> size_t { return size_; } - auto get() const -> const T* { - return data_.get(); - } + auto get() const -> const T* { return data_.get(); } - auto get() -> T* { - return data_.get(); - } + auto get() -> T* { return data_.get(); } auto release() -> T* { size_ = invalid_size; @@ -116,62 +105,63 @@ public: auto copy() const -> vec { auto v = vec(size_); - if (v) for (size_t i = 0; i < size_; ++i) v.data_[i] = data_[i]; + if (v) + for (size_t i = 0; i < size_; ++i) + v.data_[i] = data_[i]; return v; } // TODO: This can't be used for e.g. vec auto deep_copy() const -> vec { auto v = vec(size_); - if (v) for (size_t i = 0; i < size_; ++i) v.data_[i] = data_[i]->copy(); + if (v) + for (size_t i = 0; i < size_; ++i) + v.data_[i] = data_[i]->copy(); return v; } - static auto make_uninitialized(size_t size = 0) -> vec { - return vec(size); - } + static auto make_uninitialized(size_t size = 0) -> vec { return vec(size); } static auto make(size_t size, T init[]) -> vec { auto v = vec(size); - if (v) for (size_t i = 0; i < size; ++i) v.data_[i] = std::move(init[i]); + if (v) + for (size_t i = 0; i < size; ++i) + v.data_[i] = std::move(init[i]); return v; } static auto make(std::string s) -> vec { auto v = vec(s.length() + 1); - if (v) std::strcpy(v.get(), s.data()); + if (v) + std::strcpy(v.get(), s.data()); return v; } // TODO(mvsc): MVSC requires this special case: - static auto make() -> vec { - return vec(0); - } + static auto make() -> vec { return vec(0); } - template + template static auto make(Ts&&... args) -> vec { - T data[] = { std::move(args)... }; + T data[] = {std::move(args)...}; return make(sizeof...(Ts), data); } - static auto adopt(size_t size, T data[]) -> vec { - return vec(size, data); - } + static auto adopt(size_t size, T data[]) -> vec { return vec(size, data); } - static auto invalid() -> vec { - return vec(invalid_size, nullptr); - } + static auto invalid() -> vec { return vec(invalid_size, nullptr); } }; - // Ownership -template using own = std::unique_ptr; -template using ownvec = vec>; - -template -auto make_own(T* x) -> own { return own(x); } +template +using own = std::unique_ptr; +template +using ownvec = vec>; +template +auto make_own(T* x) -> own { + return own(x); +} /////////////////////////////////////////////////////////////////////////////// // Runtime Environment @@ -179,7 +169,7 @@ auto make_own(T* x) -> own { return own(x); } // Configuration class Config { -public: + public: Config() = delete; ~Config(); void operator delete(void*); @@ -189,11 +179,10 @@ public: // Implementations may provide custom methods for manipulating Configs. }; - // Engine class Engine { -public: + public: Engine() = delete; ~Engine(); void operator delete(void*); @@ -201,11 +190,10 @@ public: static auto make(own&& = Config::make()) -> own; }; - // Store class Store { -public: + public: Store() = delete; ~Store(); void operator delete(void*); @@ -213,7 +201,6 @@ public: static auto make(Engine*) -> own; }; - /////////////////////////////////////////////////////////////////////////////// // Type Representations @@ -225,24 +212,30 @@ struct Limits { uint32_t min; uint32_t max; - Limits(uint32_t min, uint32_t max = std::numeric_limits::max()) : - min(min), max(max) {} + Limits(uint32_t min, uint32_t max = std::numeric_limits::max()) + : min(min), max(max) {} }; - // Value Types enum ValKind : uint8_t { - I32, I64, F32, F64, - ANYREF = 128, FUNCREF, + I32, + I64, + F32, + F64, + ANYREF = 128, + FUNCREF, }; -inline bool is_num(ValKind k) { return k < ANYREF; } -inline bool is_ref(ValKind k) { return k >= ANYREF; } - +inline bool is_num(ValKind k) { + return k < ANYREF; +} +inline bool is_ref(ValKind k) { + return k >= ANYREF; +} class ValType { -public: + public: ValType() = delete; ~ValType(); void operator delete(void*); @@ -255,11 +248,13 @@ public: auto is_ref() const -> bool { return wasm::is_ref(kind()); } }; - // External Types enum ExternKind : uint8_t { - EXTERN_FUNC, EXTERN_GLOBAL, EXTERN_TABLE, EXTERN_MEMORY + EXTERN_FUNC, + EXTERN_GLOBAL, + EXTERN_TABLE, + EXTERN_MEMORY }; class FuncType; @@ -268,12 +263,12 @@ class TableType; class MemoryType; class ExternType { -public: + public: ExternType() = delete; ~ExternType(); void operator delete(void*); - auto copy() const-> own; + auto copy() const -> own; auto kind() const -> ExternKind; @@ -288,18 +283,16 @@ public: auto memory() const -> const MemoryType*; }; - // Function Types class FuncType : public ExternType { -public: + public: FuncType() = delete; ~FuncType(); - static auto make( - ownvec&& params = ownvec::make(), - ownvec&& results = ownvec::make() - ) -> own; + static auto make(ownvec&& params = ownvec::make(), + ownvec&& results = ownvec::make()) + -> own; auto copy() const -> own; @@ -307,11 +300,10 @@ public: auto results() const -> const ownvec&; }; - // Global Types class GlobalType : public ExternType { -public: + public: GlobalType() = delete; ~GlobalType(); @@ -322,11 +314,10 @@ public: auto mutability() const -> Mutability; }; - // Table Types class TableType : public ExternType { -public: + public: TableType() = delete; ~TableType(); @@ -337,11 +328,10 @@ public: auto limits() const -> const Limits&; }; - // Memory Types class MemoryType : public ExternType { -public: + public: MemoryType() = delete; ~MemoryType(); @@ -351,19 +341,18 @@ public: auto limits() const -> const Limits&; }; - // Import Types using Name = vec; class ImportType { -public: + public: ImportType() = delete; ~ImportType(); void operator delete(void*); - static auto make(Name&& module, Name&& name, own&&) -> - own; + static auto make(Name&& module, Name&& name, own &&) + -> own; auto copy() const -> own; auto module() const -> const Name&; @@ -371,30 +360,28 @@ public: auto type() const -> const ExternType*; }; - // Export Types class ExportType { -public: + public: ExportType() = delete; ~ExportType(); void operator delete(void*); - static auto make(Name&&, own&&) -> own; + static auto make(Name&&, own &&) -> own; auto copy() const -> own; auto name() const -> const Name&; auto type() const -> const ExternType*; }; - /////////////////////////////////////////////////////////////////////////////// // Runtime Objects // References class Ref { -public: + public: Ref() = delete; ~Ref(); void operator delete(void*); @@ -406,7 +393,6 @@ public: void set_host_info(void* info, void (*finalizer)(void*) = nullptr); }; - // Values class Val { @@ -421,7 +407,7 @@ class Val { Val(ValKind kind, impl impl) : kind_(kind), impl_(impl) {} -public: + public: Val() : kind_(ANYREF) { impl_.ref = nullptr; } Val(int32_t i) : kind_(I32) { impl_.i32 = i; } Val(int64_t i) : kind_(I64) { impl_.i64 = i; } @@ -430,12 +416,11 @@ public: Val(own&& r) : kind_(ANYREF) { impl_.ref = r.release(); } Val(Val&& that) : kind_(that.kind_), impl_(that.impl_) { - if (is_ref()) that.impl_.ref = nullptr; + if (is_ref()) + that.impl_.ref = nullptr; } - ~Val() { - reset(); - } + ~Val() { reset(); } auto is_num() const -> bool { return wasm::is_num(kind_); } auto is_ref() const -> bool { return wasm::is_ref(kind_); } @@ -445,8 +430,10 @@ public: static auto f32(float32_t x) -> Val { return Val(x); } static auto f64(float64_t x) -> Val { return Val(x); } static auto ref(own&& x) -> Val { return Val(std::move(x)); } - template inline static auto make(T x) -> Val; - template inline static auto make(own&& x) -> Val; + template + inline static auto make(T x) -> Val; + template + inline static auto make(own&& x) -> Val; void reset() { if (is_ref() && impl_.ref) { @@ -459,21 +446,38 @@ public: reset(); kind_ = that.kind_; impl_ = that.impl_; - if (is_ref()) that.impl_.ref = nullptr; + if (is_ref()) + that.impl_.ref = nullptr; } auto operator=(Val&& that) -> Val& { reset(that); return *this; - } + } auto kind() const -> ValKind { return kind_; } - auto i32() const -> int32_t { assert(kind_ == I32); return impl_.i32; } - auto i64() const -> int64_t { assert(kind_ == I64); return impl_.i64; } - auto f32() const -> float32_t { assert(kind_ == F32); return impl_.f32; } - auto f64() const -> float64_t { assert(kind_ == F64); return impl_.f64; } - auto ref() const -> Ref* { assert(is_ref()); return impl_.ref; } - template inline auto get() const -> T; + auto i32() const -> int32_t { + assert(kind_ == I32); + return impl_.i32; + } + auto i64() const -> int64_t { + assert(kind_ == I64); + return impl_.i64; + } + auto f32() const -> float32_t { + assert(kind_ == F32); + return impl_.f32; + } + auto f64() const -> float64_t { + assert(kind_ == F64); + return impl_.f64; + } + auto ref() const -> Ref* { + assert(is_ref()); + return impl_.ref; + } + template + inline auto get() const -> T; auto release_ref() -> own { assert(is_ref()); @@ -495,36 +499,66 @@ public: } }; - -template<> inline auto Val::make(int32_t x) -> Val { return Val(x); } -template<> inline auto Val::make(int64_t x) -> Val { return Val(x); } -template<> inline auto Val::make(float32_t x) -> Val { return Val(x); } -template<> inline auto Val::make(float64_t x) -> Val { return Val(x); } -template<> inline auto Val::make(own&& x) -> Val { +template <> +inline auto Val::make(int32_t x) -> Val { + return Val(x); +} +template <> +inline auto Val::make(int64_t x) -> Val { + return Val(x); +} +template <> +inline auto Val::make(float32_t x) -> Val { + return Val(x); +} +template <> +inline auto Val::make(float64_t x) -> Val { + return Val(x); +} +template <> +inline auto Val::make(own&& x) -> Val { return Val(std::move(x)); } -template<> inline auto Val::make(uint32_t x) -> Val { +template <> +inline auto Val::make(uint32_t x) -> Val { return Val(static_cast(x)); } -template<> inline auto Val::make(uint64_t x) -> Val { +template <> +inline auto Val::make(uint64_t x) -> Val { return Val(static_cast(x)); } -template<> inline auto Val::get() const -> int32_t { return i32(); } -template<> inline auto Val::get() const -> int64_t { return i64(); } -template<> inline auto Val::get() const -> float32_t { return f32(); } -template<> inline auto Val::get() const -> float64_t { return f64(); } -template<> inline auto Val::get() const -> Ref* { return ref(); } +template <> +inline auto Val::get() const -> int32_t { + return i32(); +} +template <> +inline auto Val::get() const -> int64_t { + return i64(); +} +template <> +inline auto Val::get() const -> float32_t { + return f32(); +} +template <> +inline auto Val::get() const -> float64_t { + return f64(); +} +template <> +inline auto Val::get() const -> Ref* { + return ref(); +} -template<> inline auto Val::get() const -> uint32_t { +template <> +inline auto Val::get() const -> uint32_t { return static_cast(i32()); } -template<> inline auto Val::get() const -> uint64_t { +template <> +inline auto Val::get() const -> uint64_t { return static_cast(i64()); } - // Traps using Message = vec; // null terminated @@ -532,7 +566,7 @@ using Message = vec; // null terminated class Instance; class Frame { -public: + public: Frame() = delete; ~Frame(); void operator delete(void*); @@ -546,7 +580,7 @@ public: }; class Trap : public Ref { -public: + public: Trap() = delete; ~Trap(); @@ -554,26 +588,24 @@ public: auto copy() const -> own; auto message() const -> Message; - auto origin() const -> own; // may be null + auto origin() const -> own; // may be null auto trace() const -> ownvec; // may be empty, origin first }; - // Shared objects -template +template class Shared { -public: + public: Shared() = delete; ~Shared(); void operator delete(void*); }; - // Modules class Module : public Ref { -public: + public: Module() = delete; ~Module(); @@ -591,11 +623,10 @@ public: static auto deserialize(Store*, const vec&) -> own; }; - // Foreign Objects class Foreign : public Ref { -public: + public: Foreign() = delete; ~Foreign(); @@ -603,7 +634,6 @@ public: auto copy() const -> own; }; - // Externals class Func; @@ -612,7 +642,7 @@ class Table; class Memory; class Extern : public Ref { -public: + public: Extern() = delete; ~Extern(); @@ -632,11 +662,10 @@ public: auto memory() const -> const Memory*; }; - // Function Instances class Func : public Extern { -public: + public: Func() = delete; ~Func(); @@ -644,8 +673,11 @@ public: using callback_with_env = auto (*)(void*, const Val[], Val[]) -> own; static auto make(Store*, const FuncType*, callback) -> own; - static auto make(Store*, const FuncType*, callback_with_env, - void*, void (*finalizer)(void*) = nullptr) -> own; + static auto make(Store*, + const FuncType*, + callback_with_env, + void*, + void (*finalizer)(void*) = nullptr) -> own; auto copy() const -> own; auto type() const -> own; @@ -655,11 +687,10 @@ public: auto call(const Val[] = nullptr, Val[] = nullptr) const -> own; }; - // Global Instances class Global : public Extern { -public: + public: Global() = delete; ~Global(); @@ -671,18 +702,17 @@ public: void set(const Val&); }; - // Table Instances class Table : public Extern { -public: + public: Table() = delete; ~Table(); using size_t = uint32_t; - static auto make( - Store*, const TableType*, const Ref* init = nullptr) -> own; + static auto make(Store*, const TableType*, const Ref* init = nullptr) + -> own
; auto copy() const -> own
; auto type() const -> own; @@ -692,11 +722,10 @@ public: auto grow(size_t delta, const Ref* init = nullptr) -> bool; }; - // Memory Instances class Memory : public Extern { -public: + public: Memory() = delete; ~Memory(); @@ -714,23 +743,22 @@ public: auto grow(pages_t delta) -> bool; }; - // Module Instances class Instance : public Ref { -public: + public: Instance() = delete; ~Instance(); - static auto make( - Store*, const Module*, const Extern* const[], own* = nullptr - ) -> own; + static auto make(Store*, + const Module*, + const Extern* const[], + own* = nullptr) -> own; auto copy() const -> own; auto exports() const -> ownvec; }; - /////////////////////////////////////////////////////////////////////////////// } // namespace wasm diff --git a/src/wasm-bin.cc b/src/wasm-bin.cc index eea2a4b..53ef5f0 100644 --- a/src/wasm-bin.cc +++ b/src/wasm-bin.cc @@ -9,7 +9,10 @@ namespace bin { // Encoding void encode_header(char*& ptr) { - std::memcpy(ptr, "\x00""asm\x01\x00\x00\x00", 8); + std::memcpy(ptr, + "\x00" + "asm\x01\x00\x00\x00", + 8); ptr += 8; } @@ -49,45 +52,77 @@ void encode_size32(char*& ptr, size_t n) { } } - void encode_valtype(char*& ptr, const ValType* type) { switch (type->kind()) { - case I32: *ptr++ = 0x7f; break; - case I64: *ptr++ = 0x7e; break; - case F32: *ptr++ = 0x7d; break; - case F64: *ptr++ = 0x7c; break; - case FUNCREF: *ptr++ = 0x70; break; - case ANYREF: *ptr++ = 0x6f; break; - default: assert(false); + case I32: + *ptr++ = 0x7f; + break; + case I64: + *ptr++ = 0x7e; + break; + case F32: + *ptr++ = 0x7d; + break; + case F64: + *ptr++ = 0x7c; + break; + case FUNCREF: + *ptr++ = 0x70; + break; + case ANYREF: + *ptr++ = 0x6f; + break; + default: + assert(false); } } auto zero_size(const ValType* type) -> size_t { switch (type->kind()) { - case I32: return 1; - case I64: return 1; - case F32: return 4; - case F64: return 8; - case FUNCREF: return 0; - case ANYREF: return 0; - default: assert(false); + case I32: + return 1; + case I64: + return 1; + case F32: + return 4; + case F64: + return 8; + case FUNCREF: + return 0; + case ANYREF: + return 0; + default: + assert(false); } } void encode_const_zero(char*& ptr, const ValType* type) { switch (type->kind()) { - case I32: *ptr++ = 0x41; break; - case I64: *ptr++ = 0x42; break; - case F32: *ptr++ = 0x43; break; - case F64: *ptr++ = 0x44; break; - case FUNCREF: *ptr++ = 0xd0; break; - case ANYREF: *ptr++ = 0xd0; break; - default: assert(false); + case I32: + *ptr++ = 0x41; + break; + case I64: + *ptr++ = 0x42; + break; + case F32: + *ptr++ = 0x43; + break; + case F64: + *ptr++ = 0x44; + break; + case FUNCREF: + *ptr++ = 0xd0; + break; + case ANYREF: + *ptr++ = 0xd0; + break; + default: + assert(false); } - for (int i = 0; i < zero_size(type); ++i) *ptr++ = 0; + for (int i = 0; i < zero_size(type); ++i) + *ptr++ = 0; } - auto wrapper(const FuncType* type) -> vec { auto in_arity = type->params().size(); auto out_arity = type->results().size(); @@ -97,10 +132,10 @@ auto wrapper(const FuncType* type) -> vec { encode_header(ptr); - *ptr++ = 0x01; // type section + *ptr++ = 0x01; // type section encode_size32(ptr, 12 + in_arity + out_arity); // size - *ptr++ = 1; // length - *ptr++ = 0x60; // function + *ptr++ = 1; // length + *ptr++ = 0x60; // function encode_size32(ptr, in_arity); for (size_t i = 0; i < in_arity; ++i) { encode_valtype(ptr, type->params()[i].get()); @@ -111,19 +146,19 @@ auto wrapper(const FuncType* type) -> vec { } *ptr++ = 0x02; // import section - *ptr++ = 5; // size - *ptr++ = 1; // length - *ptr++ = 0; // module length - *ptr++ = 0; // name length + *ptr++ = 5; // size + *ptr++ = 1; // length + *ptr++ = 0; // module length + *ptr++ = 0; // name length *ptr++ = 0x00; // func - *ptr++ = 0; // type index + *ptr++ = 0; // type index *ptr++ = 0x07; // export section - *ptr++ = 4; // size - *ptr++ = 1; // length - *ptr++ = 0; // name length + *ptr++ = 4; // size + *ptr++ = 1; // length + *ptr++ = 0; // name length *ptr++ = 0x00; // func - *ptr++ = 0; // func index + *ptr++ = 0; // func index assert(ptr - binary.get() == size); return binary; @@ -136,26 +171,25 @@ auto wrapper(const GlobalType* type) -> vec { encode_header(ptr); - *ptr++ = 0x06; // global section + *ptr++ = 0x06; // global section encode_size32(ptr, 5 + zero_size(type->content())); // size - *ptr++ = 1; // length + *ptr++ = 1; // length encode_valtype(ptr, type->content()); *ptr++ = (type->mutability() == VAR); encode_const_zero(ptr, type->content()); *ptr++ = 0x0b; // end *ptr++ = 0x07; // export section - *ptr++ = 4; // size - *ptr++ = 1; // length - *ptr++ = 0; // name length + *ptr++ = 4; // size + *ptr++ = 1; // length + *ptr++ = 0; // name length *ptr++ = 0x03; // global - *ptr++ = 0; // func index + *ptr++ = 0; // func index assert(ptr - binary.get() == size); return binary; } - //////////////////////////////////////////////////////////////////////////////// // Decoding @@ -189,7 +223,6 @@ void u32_skip(const byte_t*& pos) { bin::u32(pos); } - // Names auto name(const byte_t*& pos) -> Name { @@ -206,17 +239,22 @@ void name_skip(const byte_t*& pos) { pos += size; } - // Types auto valtype(const byte_t*& pos) -> own { switch (*pos++) { - case 0x7f: return ValType::make(I32); - case 0x7e: return ValType::make(I64); - case 0x7d: return ValType::make(F32); - case 0x7c: return ValType::make(F64); - case 0x70: return ValType::make(FUNCREF); - case 0x6f: return ValType::make(ANYREF); + case 0x7f: + return ValType::make(I32); + case 0x7e: + return ValType::make(I64); + case 0x7d: + return ValType::make(F32); + case 0x7c: + return ValType::make(F64); + case 0x70: + return ValType::make(FUNCREF); + case 0x6f: + return ValType::make(ANYREF); default: // TODO(wasm+): support new value types assert(false); @@ -241,7 +279,8 @@ auto limits(const byte_t*& pos) -> Limits { auto stacktype(const byte_t*& pos) -> ownvec { size_t size = bin::u32(pos); auto v = ownvec::make_uninitialized(size); - for (uint32_t i = 0; i < size; ++i) v[i] = bin::valtype(pos); + for (uint32_t i = 0; i < size; ++i) + v[i] = bin::valtype(pos); return v; } @@ -270,7 +309,6 @@ auto memorytype(const byte_t*& pos) -> own { return MemoryType::make(limits); } - void mutability_skip(const byte_t*& pos) { ++pos; } @@ -278,7 +316,8 @@ void mutability_skip(const byte_t*& pos) { void limits_skip(const byte_t*& pos) { auto tag = *pos++; bin::u32_skip(pos); - if ((tag & 0x01) != 0) bin::u32_skip(pos); + if ((tag & 0x01) != 0) + bin::u32_skip(pos); } void valtype_skip(const byte_t*& pos) { @@ -300,14 +339,13 @@ void memorytype_skip(const byte_t*& pos) { bin::limits_skip(pos); } - // Expressions void expr_skip(const byte_t*& pos) { switch (*pos++ & 0xff) { - case 0x41: // i32.const - case 0x42: // i64.const - case 0x23: // get_global + case 0x41: // i32.const + case 0x42: // i64.const + case 0x23: // get_global case 0xd2: { // ref.func bin::u32_skip(pos); } break; @@ -326,7 +364,6 @@ void expr_skip(const byte_t*& pos) { ++pos; // end } - // Sections enum sec_t : byte_t { @@ -346,7 +383,8 @@ auto section(const vec& binary, bin::sec_t sec) -> const byte_t* { auto size = bin::u32(pos); pos += size; } - if (pos == end) return nullptr; + if (pos == end) + return nullptr; bin::u32_skip(pos); return pos; } @@ -359,18 +397,19 @@ auto section_end(const vec& binary, bin::sec_t sec) -> const byte_t* { auto size = bin::u32(pos); pos += size; } - if (pos == end) return nullptr; + if (pos == end) + return nullptr; ++pos; auto size = bin::u32(pos); return pos + size; } - // Type section auto types(const vec& binary) -> ownvec { auto pos = bin::section(binary, SEC_TYPE); - if (pos == nullptr) return ownvec::make(); + if (pos == nullptr) + return ownvec::make(); size_t size = bin::u32(pos); // TODO(wasm+): support new deftypes auto v = ownvec::make_uninitialized(size); @@ -381,14 +420,13 @@ auto types(const vec& binary) -> ownvec { return v; } - // Import section -auto imports( - const vec& binary, const ownvec& types -) -> ownvec { +auto imports(const vec& binary, const ownvec& types) + -> ownvec { auto pos = bin::section(binary, SEC_IMPORT); - if (pos == nullptr) return ownvec::make(); + if (pos == nullptr) + return ownvec::make(); size_t size = bin::u32(pos); auto v = ownvec::make_uninitialized(size); for (uint32_t i = 0; i < size; ++i) { @@ -396,14 +434,23 @@ auto imports( auto name = bin::name(pos); own type; switch (*pos++) { - case 0x00: type = types[bin::u32(pos)]->copy(); break; - case 0x01: type = bin::tabletype(pos); break; - case 0x02: type = bin::memorytype(pos); break; - case 0x03: type = bin::globaltype(pos); break; - default: assert(false); + case 0x00: + type = types[bin::u32(pos)]->copy(); + break; + case 0x01: + type = bin::tabletype(pos); + break; + case 0x02: + type = bin::memorytype(pos); + break; + case 0x03: + type = bin::globaltype(pos); + break; + default: + assert(false); } - v[i] = ImportType::make( - std::move(module), std::move(name), std::move(type)); + v[i] = + ImportType::make(std::move(module), std::move(name), std::move(type)); } assert(pos = bin::section_end(binary, SEC_IMPORT)); return v; @@ -412,22 +459,21 @@ auto imports( auto count(const ownvec& imports, ExternKind kind) -> uint32_t { uint32_t n = 0; for (uint32_t i = 0; i < imports.size(); ++i) { - if (imports[i]->type()->kind() == kind) ++n; + if (imports[i]->type()->kind() == kind) + ++n; } return n; } - // Function section -auto funcs( - const vec& binary, - const ownvec& imports, const ownvec& types -) -> ownvec { +auto funcs(const vec& binary, + const ownvec& imports, + const ownvec& types) -> ownvec { auto pos = bin::section(binary, SEC_FUNC); size_t size = pos != nullptr ? bin::u32(pos) : 0; - auto v = ownvec::make_uninitialized( - size + count(imports, EXTERN_FUNC)); + auto v = + ownvec::make_uninitialized(size + count(imports, EXTERN_FUNC)); size_t j = 0; for (uint32_t i = 0; i < imports.size(); ++i) { auto et = imports[i]->type(); @@ -444,16 +490,14 @@ auto funcs( return v; } - // Global section -auto globals( - const vec& binary, const ownvec& imports -) -> ownvec { +auto globals(const vec& binary, const ownvec& imports) + -> ownvec { auto pos = bin::section(binary, SEC_GLOBAL); size_t size = pos != nullptr ? bin::u32(pos) : 0; auto v = ownvec::make_uninitialized( - size + count(imports, EXTERN_GLOBAL)); + size + count(imports, EXTERN_GLOBAL)); size_t j = 0; for (uint32_t i = 0; i < imports.size(); ++i) { auto et = imports[i]->type(); @@ -471,16 +515,14 @@ auto globals( return v; } - // Table section -auto tables( - const vec& binary, const ownvec& imports -) -> ownvec { +auto tables(const vec& binary, const ownvec& imports) + -> ownvec { auto pos = bin::section(binary, SEC_TABLE); size_t size = pos != nullptr ? bin::u32(pos) : 0; - auto v = ownvec::make_uninitialized( - size + count(imports, EXTERN_TABLE)); + auto v = ownvec::make_uninitialized(size + + count(imports, EXTERN_TABLE)); size_t j = 0; for (uint32_t i = 0; i < imports.size(); ++i) { auto et = imports[i]->type(); @@ -497,16 +539,14 @@ auto tables( return v; } - // Memory section -auto memories( - const vec& binary, const ownvec& imports -) -> ownvec { +auto memories(const vec& binary, const ownvec& imports) + -> ownvec { auto pos = bin::section(binary, SEC_MEMORY); size_t size = pos != nullptr ? bin::u32(pos) : 0; auto v = ownvec::make_uninitialized( - size + count(imports, EXTERN_MEMORY)); + size + count(imports, EXTERN_MEMORY)); size_t j = 0; for (uint32_t i = 0; i < imports.size(); ++i) { auto et = imports[i]->type(); @@ -523,15 +563,16 @@ auto memories( return v; } - // Export section auto exports(const vec& binary, - const ownvec& funcs, const ownvec& globals, - const ownvec& tables, const ownvec& memories -) -> ownvec { + const ownvec& funcs, + const ownvec& globals, + const ownvec& tables, + const ownvec& memories) -> ownvec { auto pos = bin::section(binary, SEC_EXPORT); - if (pos == nullptr) return ownvec::make(); + if (pos == nullptr) + return ownvec::make(); size_t size = bin::u32(pos); auto exports = ownvec::make_uninitialized(size); for (uint32_t i = 0; i < size; ++i) { @@ -540,11 +581,20 @@ auto exports(const vec& binary, auto index = bin::u32(pos); own type; switch (tag) { - case 0x00: type = funcs[index]->copy(); break; - case 0x01: type = tables[index]->copy(); break; - case 0x02: type = memories[index]->copy(); break; - case 0x03: type = globals[index]->copy(); break; - default: assert(false); + case 0x00: + type = funcs[index]->copy(); + break; + case 0x01: + type = tables[index]->copy(); + break; + case 0x02: + type = memories[index]->copy(); + break; + case 0x03: + type = globals[index]->copy(); + break; + default: + assert(false); } exports[i] = ExportType::make(std::move(name), std::move(type)); } diff --git a/src/wasm-c.cc b/src/wasm-c.cc index 3d2a2d5..0d401e4 100644 --- a/src/wasm-c.cc +++ b/src/wasm-c.cc @@ -1,8 +1,7 @@ +#include "wasm-v8.cc" #include "wasm.h" #include "wasm.hh" -#include "wasm-v8.cc" - using namespace wasm; extern "C" { @@ -14,7 +13,7 @@ extern "C" { extern "C++" { -template +template struct borrowed_vec { vec it; borrowed_vec(vec&& v) : it(std::move(v)) {} @@ -24,174 +23,164 @@ struct borrowed_vec { } // extern "C++" - -#define WASM_DEFINE_OWN(name, Name) \ - struct wasm_##name##_t : Name {}; \ - \ - void wasm_##name##_delete(wasm_##name##_t* x) { \ - delete x; \ - } \ - \ - extern "C++" inline auto hide_##name(Name* x) -> wasm_##name##_t* { \ - return static_cast(x); \ - } \ - extern "C++" inline auto hide_##name(const Name* x) -> const wasm_##name##_t* { \ - return static_cast(x); \ - } \ - extern "C++" inline auto reveal_##name(wasm_##name##_t* x) -> Name* { \ - return x; \ - } \ - extern "C++" inline auto reveal_##name(const wasm_##name##_t* x) -> const Name* { \ - return x; \ - } \ - extern "C++" inline auto get_##name(own& x) -> wasm_##name##_t* { \ - return hide_##name(x.get()); \ - } \ - extern "C++" inline auto get_##name(const own& x) -> const wasm_##name##_t* { \ - return hide_##name(x.get()); \ - } \ - extern "C++" inline auto release_##name(own&& x) -> wasm_##name##_t* { \ - return hide_##name(x.release()); \ - } \ - extern "C++" inline auto adopt_##name(wasm_##name##_t* x) -> own { \ - return make_own(x); \ +#define WASM_DEFINE_OWN(name, Name) \ + struct wasm_##name##_t : Name {}; \ + \ + void wasm_##name##_delete(wasm_##name##_t* x) { delete x; } \ + \ + extern "C++" inline auto hide_##name(Name* x)->wasm_##name##_t* { \ + return static_cast(x); \ + } \ + extern "C++" inline auto hide_##name(const Name* x) \ + ->const wasm_##name##_t* { \ + return static_cast(x); \ + } \ + extern "C++" inline auto reveal_##name(wasm_##name##_t* x)->Name* { \ + return x; \ + } \ + extern "C++" inline auto reveal_##name(const wasm_##name##_t* x) \ + ->const Name* { \ + return x; \ + } \ + extern "C++" inline auto get_##name(own& x)->wasm_##name##_t* { \ + return hide_##name(x.get()); \ + } \ + extern "C++" inline auto get_##name(const own& x) \ + ->const wasm_##name##_t* { \ + return hide_##name(x.get()); \ + } \ + extern "C++" inline auto release_##name(own&& x)->wasm_##name##_t* { \ + return hide_##name(x.release()); \ + } \ + extern "C++" inline auto adopt_##name(wasm_##name##_t* x)->own { \ + return make_own(x); \ } - // Vectors -#define WASM_DEFINE_VEC_BASE(name, Name, vec, ptr_or_none) \ - static_assert( \ - sizeof(wasm_##name##_vec_t) == sizeof(vec), \ - "C/C++ incompatibility" \ - ); \ - static_assert( \ - sizeof(wasm_##name##_t ptr_or_none) == sizeof(vec::elem_type), \ - "C/C++ incompatibility" \ - ); \ - \ - extern "C++" inline auto hide_##name##_vec(vec& v) \ - -> wasm_##name##_vec_t* { \ - return reinterpret_cast(&v); \ - } \ - extern "C++" inline auto hide_##name##_vec(const vec& v) \ - -> const wasm_##name##_vec_t* { \ - return reinterpret_cast(&v); \ - } \ - extern "C++" inline auto hide_##name##_vec(vec::elem_type* v) \ - -> wasm_##name##_t ptr_or_none* { \ - return reinterpret_cast(v); \ - } \ - extern "C++" inline auto hide_##name##_vec(const vec::elem_type* v) \ - -> wasm_##name##_t ptr_or_none const* { \ - return reinterpret_cast(v); \ - } \ +#define WASM_DEFINE_VEC_BASE(name, Name, vec, ptr_or_none) \ + static_assert(sizeof(wasm_##name##_vec_t) == sizeof(vec), \ + "C/C++ incompatibility"); \ + static_assert( \ + sizeof(wasm_##name##_t ptr_or_none) == sizeof(vec::elem_type), \ + "C/C++ incompatibility"); \ + \ + extern "C++" inline auto hide_##name##_vec(vec& v) \ + ->wasm_##name##_vec_t* { \ + return reinterpret_cast(&v); \ + } \ + extern "C++" inline auto hide_##name##_vec(const vec& v) \ + ->const wasm_##name##_vec_t* { \ + return reinterpret_cast(&v); \ + } \ + extern "C++" inline auto hide_##name##_vec(vec::elem_type* v) \ + ->wasm_##name##_t ptr_or_none* { \ + return reinterpret_cast(v); \ + } \ + extern "C++" inline auto hide_##name##_vec(const vec::elem_type* v) \ + ->wasm_##name##_t ptr_or_none const* { \ + return reinterpret_cast(v); \ + } \ extern "C++" inline auto reveal_##name##_vec(wasm_##name##_t ptr_or_none* v) \ - -> vec::elem_type* { \ - return reinterpret_cast::elem_type*>(v); \ - } \ - extern "C++" inline auto reveal_##name##_vec(wasm_##name##_t ptr_or_none const* v) \ - -> const vec::elem_type* { \ - return reinterpret_cast::elem_type*>(v); \ - } \ - extern "C++" inline auto get_##name##_vec(vec& v) \ - -> wasm_##name##_vec_t { \ - wasm_##name##_vec_t v2 = { v.size(), hide_##name##_vec(v.get()) }; \ - return v2; \ - } \ - extern "C++" inline auto get_##name##_vec(const vec& v) \ - -> const wasm_##name##_vec_t { \ - wasm_##name##_vec_t v2 = { \ - v.size(), const_cast(hide_##name##_vec(v.get())) }; \ - return v2; \ - } \ - extern "C++" inline auto release_##name##_vec(vec&& v) \ - -> wasm_##name##_vec_t { \ - wasm_##name##_vec_t v2 = { v.size(), hide_##name##_vec(v.release()) }; \ - return v2; \ - } \ - extern "C++" inline auto adopt_##name##_vec(wasm_##name##_vec_t* v) \ - -> vec { \ - return vec::adopt(v->size, reveal_##name##_vec(v->data)); \ - } \ - extern "C++" inline auto borrow_##name##_vec(const wasm_##name##_vec_t* v) \ - -> borrowed_vec::elem_type> { \ - return borrowed_vec::elem_type>(vec::adopt(v->size, reveal_##name##_vec(v->data))); \ - } \ - \ - void wasm_##name##_vec_new_uninitialized( \ - wasm_##name##_vec_t* out, size_t size \ - ) { \ - *out = release_##name##_vec(vec::make_uninitialized(size)); \ - } \ - void wasm_##name##_vec_new_empty(wasm_##name##_vec_t* out) { \ - wasm_##name##_vec_new_uninitialized(out, 0); \ - } \ - \ - void wasm_##name##_vec_delete(wasm_##name##_vec_t* v) { \ - adopt_##name##_vec(v); \ + ->vec::elem_type* { \ + return reinterpret_cast::elem_type*>(v); \ + } \ + extern "C++" inline auto reveal_##name##_vec( \ + wasm_##name##_t ptr_or_none const* v) \ + ->const vec::elem_type* { \ + return reinterpret_cast::elem_type*>(v); \ + } \ + extern "C++" inline auto get_##name##_vec(vec& v) \ + ->wasm_##name##_vec_t { \ + wasm_##name##_vec_t v2 = {v.size(), hide_##name##_vec(v.get())}; \ + return v2; \ + } \ + extern "C++" inline auto get_##name##_vec(const vec& v) \ + ->const wasm_##name##_vec_t { \ + wasm_##name##_vec_t v2 = { \ + v.size(), \ + const_cast(hide_##name##_vec(v.get()))}; \ + return v2; \ + } \ + extern "C++" inline auto release_##name##_vec(vec&& v) \ + ->wasm_##name##_vec_t { \ + wasm_##name##_vec_t v2 = {v.size(), hide_##name##_vec(v.release())}; \ + return v2; \ + } \ + extern "C++" inline auto adopt_##name##_vec(wasm_##name##_vec_t* v) \ + ->vec { \ + return vec::adopt(v->size, reveal_##name##_vec(v->data)); \ + } \ + extern "C++" inline auto borrow_##name##_vec(const wasm_##name##_vec_t* v) \ + ->borrowed_vec::elem_type> { \ + return borrowed_vec::elem_type>( \ + vec::adopt(v->size, reveal_##name##_vec(v->data))); \ + } \ + \ + void wasm_##name##_vec_new_uninitialized(wasm_##name##_vec_t* out, \ + size_t size) { \ + *out = release_##name##_vec(vec::make_uninitialized(size)); \ + } \ + void wasm_##name##_vec_new_empty(wasm_##name##_vec_t* out) { \ + wasm_##name##_vec_new_uninitialized(out, 0); \ + } \ + \ + void wasm_##name##_vec_delete(wasm_##name##_vec_t* v) { \ + adopt_##name##_vec(v); \ } // Vectors with no ownership management of elements -#define WASM_DEFINE_VEC_PLAIN(name, Name) \ - WASM_DEFINE_VEC_BASE(name, Name, vec, ) \ - \ - void wasm_##name##_vec_new( \ - wasm_##name##_vec_t* out, \ - size_t size, \ - const wasm_##name##_t data[] \ - ) { \ - auto v2 = vec::make_uninitialized(size); \ - if (v2.size() != 0) { \ - memcpy(v2.get(), data, size * sizeof(wasm_##name##_t)); \ - } \ - *out = release_##name##_vec(std::move(v2)); \ - } \ - \ - void wasm_##name##_vec_copy( \ - wasm_##name##_vec_t* out, wasm_##name##_vec_t* v \ - ) { \ - wasm_##name##_vec_new(out, v->size, v->data); \ +#define WASM_DEFINE_VEC_PLAIN(name, Name) \ + WASM_DEFINE_VEC_BASE(name, Name, vec, ) \ + \ + void wasm_##name##_vec_new(wasm_##name##_vec_t* out, size_t size, \ + const wasm_##name##_t data[]) { \ + auto v2 = vec::make_uninitialized(size); \ + if (v2.size() != 0) { \ + memcpy(v2.get(), data, size * sizeof(wasm_##name##_t)); \ + } \ + *out = release_##name##_vec(std::move(v2)); \ + } \ + \ + void wasm_##name##_vec_copy(wasm_##name##_vec_t* out, \ + wasm_##name##_vec_t* v) { \ + wasm_##name##_vec_new(out, v->size, v->data); \ } // Vectors that own their elements -#define WASM_DEFINE_VEC_OWN(name, Name) \ - WASM_DEFINE_VEC_BASE(name, Name, ownvec, *) \ - \ - void wasm_##name##_vec_new( \ - wasm_##name##_vec_t* out, \ - size_t size, \ - wasm_##name##_t* const data[] \ - ) { \ - auto v2 = ownvec::make_uninitialized(size); \ - for (size_t i = 0; i < v2.size(); ++i) { \ - v2[i] = adopt_##name(data[i]); \ - } \ - *out = release_##name##_vec(std::move(v2)); \ - } \ - \ - void wasm_##name##_vec_copy( \ - wasm_##name##_vec_t* out, wasm_##name##_vec_t* v \ - ) { \ - auto v2 = ownvec::make_uninitialized(v->size); \ - for (size_t i = 0; i < v2.size(); ++i) { \ - v2[i] = adopt_##name(wasm_##name##_copy(v->data[i])); \ - } \ - *out = release_##name##_vec(std::move(v2)); \ +#define WASM_DEFINE_VEC_OWN(name, Name) \ + WASM_DEFINE_VEC_BASE(name, Name, ownvec, *) \ + \ + void wasm_##name##_vec_new(wasm_##name##_vec_t* out, size_t size, \ + wasm_##name##_t* const data[]) { \ + auto v2 = ownvec::make_uninitialized(size); \ + for (size_t i = 0; i < v2.size(); ++i) { \ + v2[i] = adopt_##name(data[i]); \ + } \ + *out = release_##name##_vec(std::move(v2)); \ + } \ + \ + void wasm_##name##_vec_copy(wasm_##name##_vec_t* out, \ + wasm_##name##_vec_t* v) { \ + auto v2 = ownvec::make_uninitialized(v->size); \ + for (size_t i = 0; i < v2.size(); ++i) { \ + v2[i] = adopt_##name(wasm_##name##_copy(v->data[i])); \ + } \ + *out = release_##name##_vec(std::move(v2)); \ } extern "C++" { -template -inline auto is_empty(T* p) -> bool { return !p; } +template +inline auto is_empty(T* p) -> bool { + return !p; +} } - // Byte vectors using byte = byte_t; WASM_DEFINE_VEC_PLAIN(byte, byte) - /////////////////////////////////////////////////////////////////////////////// // Runtime Environment @@ -203,7 +192,6 @@ wasm_config_t* wasm_config_new() { return release_config(Config::make()); } - // Engine WASM_DEFINE_OWN(engine, Engine) @@ -216,7 +204,6 @@ wasm_engine_t* wasm_engine_new_with_config(wasm_config_t* config) { return release_engine(Engine::make(adopt_config(config))); } - // Stores WASM_DEFINE_OWN(store, Store) @@ -225,22 +212,23 @@ wasm_store_t* wasm_store_new(wasm_engine_t* engine) { return release_store(Store::make(engine)); }; - /////////////////////////////////////////////////////////////////////////////// // Type Representations // Type attributes -extern "C++" inline auto hide_mutability(Mutability mutability) -> wasm_mutability_t { +extern "C++" inline auto hide_mutability(Mutability mutability) + -> wasm_mutability_t { return static_cast(mutability); } -extern "C++" inline auto reveal_mutability(wasm_mutability_t mutability) -> Mutability { +extern "C++" inline auto reveal_mutability(wasm_mutability_t mutability) + -> Mutability { return static_cast(mutability); } - -extern "C++" inline auto hide_limits(const Limits& limits) -> const wasm_limits_t* { +extern "C++" inline auto hide_limits(const Limits& limits) + -> const wasm_limits_t* { return reinterpret_cast(&limits); } @@ -248,7 +236,6 @@ extern "C++" inline auto reveal_limits(wasm_limits_t limits) -> Limits { return Limits(limits.min, limits.max); } - extern "C++" inline auto hide_valkind(ValKind kind) -> wasm_valkind_t { return static_cast(kind); } @@ -257,28 +244,25 @@ extern "C++" inline auto reveal_valkind(wasm_valkind_t kind) -> ValKind { return static_cast(kind); } - extern "C++" inline auto hide_externkind(ExternKind kind) -> wasm_externkind_t { return static_cast(kind); } -extern "C++" inline auto reveal_externkind(wasm_externkind_t kind) -> ExternKind { +extern "C++" inline auto reveal_externkind(wasm_externkind_t kind) + -> ExternKind { return static_cast(kind); } - - // Generic -#define WASM_DEFINE_TYPE(name, Name) \ - WASM_DEFINE_OWN(name, Name) \ - WASM_DEFINE_VEC_OWN(name, Name) \ - \ +#define WASM_DEFINE_TYPE(name, Name) \ + WASM_DEFINE_OWN(name, Name) \ + WASM_DEFINE_VEC_OWN(name, Name) \ + \ wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t* t) { \ - return release_##name(t->copy()); \ + return release_##name(t->copy()); \ } - // Value Types WASM_DEFINE_TYPE(valtype, ValType) @@ -291,16 +275,14 @@ wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t* t) { return hide_valkind(t->kind()); } - // Function Types WASM_DEFINE_TYPE(functype, FuncType) -wasm_functype_t* wasm_functype_new( - wasm_valtype_vec_t* params, wasm_valtype_vec_t* results -) { +wasm_functype_t* wasm_functype_new(wasm_valtype_vec_t* params, + wasm_valtype_vec_t* results) { return release_functype( - FuncType::make(adopt_valtype_vec(params), adopt_valtype_vec(results))); + FuncType::make(adopt_valtype_vec(params), adopt_valtype_vec(results))); } const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t* ft) { @@ -311,18 +293,14 @@ const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t* ft) { return hide_valtype_vec(ft->results()); } - // Global Types WASM_DEFINE_TYPE(globaltype, GlobalType) -wasm_globaltype_t* wasm_globaltype_new( - wasm_valtype_t* content, wasm_mutability_t mutability -) { - return release_globaltype(GlobalType::make( - adopt_valtype(content), - reveal_mutability(mutability) - )); +wasm_globaltype_t* wasm_globaltype_new(wasm_valtype_t* content, + wasm_mutability_t mutability) { + return release_globaltype( + GlobalType::make(adopt_valtype(content), reveal_mutability(mutability))); } const wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t* gt) { @@ -333,15 +311,14 @@ wasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t* gt) { return hide_mutability(gt->mutability()); } - // Table Types WASM_DEFINE_TYPE(tabletype, TableType) -wasm_tabletype_t* wasm_tabletype_new( - wasm_valtype_t* element, const wasm_limits_t* limits -) { - return release_tabletype(TableType::make(adopt_valtype(element), reveal_limits(*limits))); +wasm_tabletype_t* wasm_tabletype_new(wasm_valtype_t* element, + const wasm_limits_t* limits) { + return release_tabletype( + TableType::make(adopt_valtype(element), reveal_limits(*limits))); } const wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t* tt) { @@ -352,7 +329,6 @@ const wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t* tt) { return hide_limits(tt->limits()); } - // Memory Types WASM_DEFINE_TYPE(memorytype, MemoryType) @@ -365,7 +341,6 @@ const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t* mt) { return hide_limits(mt->limits()); } - // Extern Types WASM_DEFINE_TYPE(externtype, ExternType) @@ -388,78 +363,80 @@ wasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t* mt) { } const wasm_externtype_t* wasm_functype_as_externtype_const( - const wasm_functype_t* ft -) { + const wasm_functype_t* ft) { return hide_externtype(static_cast(ft)); } const wasm_externtype_t* wasm_globaltype_as_externtype_const( - const wasm_globaltype_t* gt -) { + const wasm_globaltype_t* gt) { return hide_externtype(static_cast(gt)); } const wasm_externtype_t* wasm_tabletype_as_externtype_const( - const wasm_tabletype_t* tt -) { + const wasm_tabletype_t* tt) { return hide_externtype(static_cast(tt)); } const wasm_externtype_t* wasm_memorytype_as_externtype_const( - const wasm_memorytype_t* mt -) { + const wasm_memorytype_t* mt) { return hide_externtype(static_cast(mt)); } wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t* et) { return et->kind() == EXTERN_FUNC - ? hide_functype(static_cast(reveal_externtype(et))) : nullptr; + ? hide_functype(static_cast(reveal_externtype(et))) + : nullptr; } wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t* et) { return et->kind() == EXTERN_GLOBAL - ? hide_globaltype(static_cast(reveal_externtype(et))) : nullptr; + ? hide_globaltype(static_cast(reveal_externtype(et))) + : nullptr; } wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t* et) { return et->kind() == EXTERN_TABLE - ? hide_tabletype(static_cast(reveal_externtype(et))) : nullptr; + ? hide_tabletype(static_cast(reveal_externtype(et))) + : nullptr; } wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t* et) { return et->kind() == EXTERN_MEMORY - ? hide_memorytype(static_cast(reveal_externtype(et))) : nullptr; + ? hide_memorytype(static_cast(reveal_externtype(et))) + : nullptr; } const wasm_functype_t* wasm_externtype_as_functype_const( - const wasm_externtype_t* et -) { - return et->kind() == EXTERN_FUNC - ? hide_functype(static_cast(reveal_externtype(et))) : nullptr; + const wasm_externtype_t* et) { + return et->kind() == EXTERN_FUNC ? hide_functype(static_cast( + reveal_externtype(et))) + : nullptr; } const wasm_globaltype_t* wasm_externtype_as_globaltype_const( - const wasm_externtype_t* et -) { + const wasm_externtype_t* et) { return et->kind() == EXTERN_GLOBAL - ? hide_globaltype(static_cast(reveal_externtype(et))) : nullptr; + ? hide_globaltype( + static_cast(reveal_externtype(et))) + : nullptr; } const wasm_tabletype_t* wasm_externtype_as_tabletype_const( - const wasm_externtype_t* et -) { + const wasm_externtype_t* et) { return et->kind() == EXTERN_TABLE - ? hide_tabletype(static_cast(reveal_externtype(et))) : nullptr; + ? hide_tabletype( + static_cast(reveal_externtype(et))) + : nullptr; } const wasm_memorytype_t* wasm_externtype_as_memorytype_const( - const wasm_externtype_t* et -) { + const wasm_externtype_t* et) { return et->kind() == EXTERN_MEMORY - ? hide_memorytype(static_cast(reveal_externtype(et))) : nullptr; + ? hide_memorytype( + static_cast(reveal_externtype(et))) + : nullptr; } - // Import Types WASM_DEFINE_TYPE(importtype, ImportType) -wasm_importtype_t* wasm_importtype_new( - wasm_name_t* module, wasm_name_t* name, wasm_externtype_t* type -) { - return release_importtype( - ImportType::make(adopt_byte_vec(module), adopt_byte_vec(name), adopt_externtype(type))); +wasm_importtype_t* wasm_importtype_new(wasm_name_t* module, + wasm_name_t* name, + wasm_externtype_t* type) { + return release_importtype(ImportType::make( + adopt_byte_vec(module), adopt_byte_vec(name), adopt_externtype(type))); } const wasm_name_t* wasm_importtype_module(const wasm_importtype_t* it) { @@ -474,16 +451,14 @@ const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t* it) { return hide_externtype(it->type()); } - // Export Types WASM_DEFINE_TYPE(exporttype, ExportType) -wasm_exporttype_t* wasm_exporttype_new( - wasm_name_t* name, wasm_externtype_t* type -) { +wasm_exporttype_t* wasm_exporttype_new(wasm_name_t* name, + wasm_externtype_t* type) { return release_exporttype( - ExportType::make(adopt_byte_vec(name), adopt_externtype(type))); + ExportType::make(adopt_byte_vec(name), adopt_externtype(type))); } const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t* et) { @@ -494,105 +469,130 @@ const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t* et) { return hide_externtype(et->type()); } - /////////////////////////////////////////////////////////////////////////////// // Runtime Values // References -#define WASM_DEFINE_REF_BASE(name, Name) \ - WASM_DEFINE_OWN(name, Name) \ - \ - wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t* t) { \ - return release_##name(t->copy()); \ - } \ - \ - bool wasm_##name##_same(const wasm_##name##_t* t1, const wasm_##name##_t* t2) { \ - return t1->same(t2); \ - } \ - \ - void* wasm_##name##_get_host_info(const wasm_##name##_t* r) { \ - return r->get_host_info(); \ - } \ +#define WASM_DEFINE_REF_BASE(name, Name) \ + WASM_DEFINE_OWN(name, Name) \ + \ + wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t* t) { \ + return release_##name(t->copy()); \ + } \ + \ + bool wasm_##name##_same(const wasm_##name##_t* t1, \ + const wasm_##name##_t* t2) { \ + return t1->same(t2); \ + } \ + \ + void* wasm_##name##_get_host_info(const wasm_##name##_t* r) { \ + return r->get_host_info(); \ + } \ void wasm_##name##_set_host_info(wasm_##name##_t* r, void* info) { \ - r->set_host_info(info); \ - } \ - void wasm_##name##_set_host_info_with_finalizer( \ - wasm_##name##_t* r, void* info, void (*finalizer)(void*) \ - ) { \ - r->set_host_info(info, finalizer); \ + r->set_host_info(info); \ + } \ + void wasm_##name##_set_host_info_with_finalizer( \ + wasm_##name##_t* r, void* info, void (*finalizer)(void*)) { \ + r->set_host_info(info, finalizer); \ } -#define WASM_DEFINE_REF(name, Name) \ - WASM_DEFINE_REF_BASE(name, Name) \ - \ - wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t* r) { \ - return hide_ref(static_cast(reveal_##name(r))); \ - } \ - wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t* r) { \ - return hide_##name(static_cast(reveal_ref(r))); \ - } \ - \ +#define WASM_DEFINE_REF(name, Name) \ + WASM_DEFINE_REF_BASE(name, Name) \ + \ + wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t* r) { \ + return hide_ref(static_cast(reveal_##name(r))); \ + } \ + wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t* r) { \ + return hide_##name(static_cast(reveal_ref(r))); \ + } \ + \ const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t* r) { \ - return hide_ref(static_cast(reveal_##name(r))); \ - } \ + return hide_ref(static_cast(reveal_##name(r))); \ + } \ const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t* r) { \ - return hide_##name(static_cast(reveal_ref(r))); \ + return hide_##name(static_cast(reveal_ref(r))); \ } #define WASM_DEFINE_SHARABLE_REF(name, Name) \ - WASM_DEFINE_REF(name, Name) \ + WASM_DEFINE_REF(name, Name) \ WASM_DEFINE_OWN(shared_##name, Shared) - WASM_DEFINE_REF_BASE(ref, Ref) - // Values extern "C++" { inline auto is_empty(wasm_val_t v) -> bool { - return !is_ref(reveal_valkind(v.kind)) || !v.of.ref; + return !is_ref(reveal_valkind(v.kind)) || !v.of.ref; } inline auto hide_val(Val v) -> wasm_val_t { - wasm_val_t v2 = { hide_valkind(v.kind()) }; + wasm_val_t v2 = {hide_valkind(v.kind())}; switch (v.kind()) { - case I32: v2.of.i32 = v.i32(); break; - case I64: v2.of.i64 = v.i64(); break; - case F32: v2.of.f32 = v.f32(); break; - case F64: v2.of.f64 = v.f64(); break; + case I32: + v2.of.i32 = v.i32(); + break; + case I64: + v2.of.i64 = v.i64(); + break; + case F32: + v2.of.f32 = v.f32(); + break; + case F64: + v2.of.f64 = v.f64(); + break; case ANYREF: - case FUNCREF: v2.of.ref = hide_ref(v.ref()); break; - default: assert(false); + case FUNCREF: + v2.of.ref = hide_ref(v.ref()); + break; + default: + assert(false); } return v2; } inline auto release_val(Val v) -> wasm_val_t { - wasm_val_t v2 = { hide_valkind(v.kind()) }; + wasm_val_t v2 = {hide_valkind(v.kind())}; switch (v.kind()) { - case I32: v2.of.i32 = v.i32(); break; - case I64: v2.of.i64 = v.i64(); break; - case F32: v2.of.f32 = v.f32(); break; - case F64: v2.of.f64 = v.f64(); break; + case I32: + v2.of.i32 = v.i32(); + break; + case I64: + v2.of.i64 = v.i64(); + break; + case F32: + v2.of.f32 = v.f32(); + break; + case F64: + v2.of.f64 = v.f64(); + break; case ANYREF: - case FUNCREF: v2.of.ref = release_ref(v.release_ref()); break; - default: assert(false); + case FUNCREF: + v2.of.ref = release_ref(v.release_ref()); + break; + default: + assert(false); } return v2; } inline auto adopt_val(wasm_val_t v) -> Val { switch (reveal_valkind(v.kind)) { - case I32: return Val(v.of.i32); - case I64: return Val(v.of.i64); - case F32: return Val(v.of.f32); - case F64: return Val(v.of.f64); + case I32: + return Val(v.of.i32); + case I64: + return Val(v.of.i64); + case F32: + return Val(v.of.f32); + case F64: + return Val(v.of.f64); case ANYREF: - case FUNCREF: return Val(adopt_ref(v.of.ref)); - default: assert(false); + case FUNCREF: + return Val(adopt_ref(v.of.ref)); + default: + assert(false); } } @@ -600,31 +600,44 @@ struct borrowed_val { Val it; borrowed_val(Val&& v) : it(std::move(v)) {} borrowed_val(borrowed_val&& that) : it(std::move(that.it)) {} - ~borrowed_val() { if (it.is_ref()) it.release_ref().release(); } + ~borrowed_val() { + if (it.is_ref()) + it.release_ref().release(); + } }; inline auto borrow_val(const wasm_val_t* v) -> borrowed_val { Val v2; switch (reveal_valkind(v->kind)) { - case I32: v2 = Val(v->of.i32); break; - case I64: v2 = Val(v->of.i64); break; - case F32: v2 = Val(v->of.f32); break; - case F64: v2 = Val(v->of.f64); break; + case I32: + v2 = Val(v->of.i32); + break; + case I64: + v2 = Val(v->of.i64); + break; + case F32: + v2 = Val(v->of.f32); + break; + case F64: + v2 = Val(v->of.f64); + break; case ANYREF: - case FUNCREF: v2 = Val(adopt_ref(v->of.ref)); break; - default: assert(false); + case FUNCREF: + v2 = Val(adopt_ref(v->of.ref)); + break; + default: + assert(false); } return borrowed_val(std::move(v2)); } } // extern "C++" - WASM_DEFINE_VEC_BASE(val, Val, vec, ) -void wasm_val_vec_new( - wasm_val_vec_t* out, size_t size, wasm_val_t const data[] -) { +void wasm_val_vec_new(wasm_val_vec_t* out, + size_t size, + wasm_val_t const data[]) { auto v2 = vec::make_uninitialized(size); for (size_t i = 0; i < v2.size(); ++i) { v2[i] = adopt_val(data[i]); @@ -642,7 +655,6 @@ void wasm_val_vec_copy(wasm_val_vec_t* out, wasm_val_vec_t* v) { *out = release_val_vec(std::move(v2)); } - void wasm_val_delete(wasm_val_t* v) { if (is_ref(reveal_valkind(v->kind))) { adopt_ref(v->of.ref); @@ -656,7 +668,6 @@ void wasm_val_copy(wasm_val_t* out, const wasm_val_t* v) { } } - /////////////////////////////////////////////////////////////////////////////// // Runtime Objects @@ -684,7 +695,6 @@ size_t wasm_frame_module_offset(const wasm_frame_t* frame) { return reveal_frame(frame)->module_offset(); } - // Traps WASM_DEFINE_REF(trap, Trap) @@ -706,7 +716,6 @@ void wasm_trap_trace(const wasm_trap_t* trap, wasm_frame_vec_t* out) { *out = release_frame_vec(reveal_trap(trap)->trace()); } - // Foreign Objects WASM_DEFINE_REF(foreign, Foreign) @@ -715,7 +724,6 @@ wasm_foreign_t* wasm_foreign_new(wasm_store_t* store) { return release_foreign(Foreign::make(store)); } - // Modules WASM_DEFINE_SHARABLE_REF(module, Module) @@ -725,23 +733,19 @@ bool wasm_module_validate(wasm_store_t* store, const wasm_byte_vec_t* binary) { return Module::validate(store, binary_.it); } -wasm_module_t* wasm_module_new( - wasm_store_t* store, const wasm_byte_vec_t* binary -) { +wasm_module_t* wasm_module_new(wasm_store_t* store, + const wasm_byte_vec_t* binary) { auto binary_ = borrow_byte_vec(binary); return release_module(Module::make(store, binary_.it)); } - -void wasm_module_imports( - const wasm_module_t* module, wasm_importtype_vec_t* out -) { +void wasm_module_imports(const wasm_module_t* module, + wasm_importtype_vec_t* out) { *out = release_importtype_vec(reveal_module(module)->imports()); } -void wasm_module_exports( - const wasm_module_t* module, wasm_exporttype_vec_t* out -) { +void wasm_module_exports(const wasm_module_t* module, + wasm_exporttype_vec_t* out) { *out = release_exporttype_vec(reveal_module(module)->exports()); } @@ -749,9 +753,8 @@ void wasm_module_serialize(const wasm_module_t* module, wasm_byte_vec_t* out) { *out = release_byte_vec(reveal_module(module)->serialize()); } -wasm_module_t* wasm_module_deserialize( - wasm_store_t* store, const wasm_byte_vec_t* binary -) { +wasm_module_t* wasm_module_deserialize(wasm_store_t* store, + const wasm_byte_vec_t* binary) { auto binary_ = borrow_byte_vec(binary); return release_module(Module::deserialize(store, binary_.it)); } @@ -760,11 +763,11 @@ wasm_shared_module_t* wasm_module_share(const wasm_module_t* module) { return release_shared_module(reveal_module(module)->share()); } -wasm_module_t* wasm_module_obtain(wasm_store_t* store, const wasm_shared_module_t* shared) { +wasm_module_t* wasm_module_obtain(wasm_store_t* store, + const wasm_shared_module_t* shared) { return release_module(Module::obtain(store, shared)); } - // Function Instances WASM_DEFINE_REF(func, Func) @@ -782,35 +785,37 @@ struct wasm_callback_env_t { void (*finalizer)(void*); }; -auto wasm_callback_with_env( - void* env, const Val args[], Val results[] -) -> own { +auto wasm_callback_with_env(void* env, const Val args[], Val results[]) + -> own { auto t = static_cast(env); - return adopt_trap(t->callback(t->env, hide_val_vec(args), hide_val_vec(results))); + return adopt_trap( + t->callback(t->env, hide_val_vec(args), hide_val_vec(results))); } void wasm_callback_env_finalizer(void* env) { auto t = static_cast(env); - if (t->finalizer) t->finalizer(t->env); + if (t->finalizer) + t->finalizer(t->env); delete t; } } // extern "C++" -wasm_func_t* wasm_func_new( - wasm_store_t* store, const wasm_functype_t* type, - wasm_func_callback_t callback -) { - return release_func(Func::make( - store, type, wasm_callback, reinterpret_cast(callback))); +wasm_func_t* wasm_func_new(wasm_store_t* store, + const wasm_functype_t* type, + wasm_func_callback_t callback) { + return release_func(Func::make(store, type, wasm_callback, + reinterpret_cast(callback))); } -wasm_func_t *wasm_func_new_with_env( - wasm_store_t* store, const wasm_functype_t* type, - wasm_func_callback_with_env_t callback, void *env, void (*finalizer)(void*) -) { +wasm_func_t* wasm_func_new_with_env(wasm_store_t* store, + const wasm_functype_t* type, + wasm_func_callback_with_env_t callback, + void* env, + void (*finalizer)(void*)) { auto env2 = new wasm_callback_env_t{callback, env, finalizer}; - return release_func(Func::make(store, type, wasm_callback_with_env, env2, wasm_callback_env_finalizer)); + return release_func(Func::make(store, type, wasm_callback_with_env, env2, + wasm_callback_env_finalizer)); } wasm_functype_t* wasm_func_type(const wasm_func_t* func) { @@ -825,20 +830,20 @@ size_t wasm_func_result_arity(const wasm_func_t* func) { return func->result_arity(); } -wasm_trap_t* wasm_func_call( - const wasm_func_t* func, const wasm_val_t args[], wasm_val_t results[] -) { - return release_trap(func->call(reveal_val_vec(args), reveal_val_vec(results))); +wasm_trap_t* wasm_func_call(const wasm_func_t* func, + const wasm_val_t args[], + wasm_val_t results[]) { + return release_trap( + func->call(reveal_val_vec(args), reveal_val_vec(results))); } - // Global Instances WASM_DEFINE_REF(global, Global) -wasm_global_t* wasm_global_new( - wasm_store_t* store, const wasm_globaltype_t* type, const wasm_val_t* val -) { +wasm_global_t* wasm_global_new(wasm_store_t* store, + const wasm_globaltype_t* type, + const wasm_val_t* val) { auto val_ = borrow_val(val); return release_global(Global::make(store, type, val_.it)); } @@ -856,14 +861,13 @@ void wasm_global_set(wasm_global_t* global, const wasm_val_t* val) { global->set(val_.it); } - // Table Instances WASM_DEFINE_REF(table, Table) -wasm_table_t* wasm_table_new( - wasm_store_t* store, const wasm_tabletype_t* type, wasm_ref_t* ref -) { +wasm_table_t* wasm_table_new(wasm_store_t* store, + const wasm_tabletype_t* type, + wasm_ref_t* ref) { return release_table(Table::make(store, type, ref)); } @@ -875,9 +879,9 @@ wasm_ref_t* wasm_table_get(const wasm_table_t* table, wasm_table_size_t index) { return release_ref(table->get(index)); } -bool wasm_table_set( - wasm_table_t* table, wasm_table_size_t index, wasm_ref_t* ref -) { +bool wasm_table_set(wasm_table_t* table, + wasm_table_size_t index, + wasm_ref_t* ref) { return table->set(index, ref); } @@ -885,20 +889,18 @@ wasm_table_size_t wasm_table_size(const wasm_table_t* table) { return table->size(); } -bool wasm_table_grow( - wasm_table_t* table, wasm_table_size_t delta, wasm_ref_t* ref -) { +bool wasm_table_grow(wasm_table_t* table, + wasm_table_size_t delta, + wasm_ref_t* ref) { return table->grow(delta, ref); } - // Memory Instances WASM_DEFINE_REF(memory, Memory) -wasm_memory_t* wasm_memory_new( - wasm_store_t* store, const wasm_memorytype_t* type -) { +wasm_memory_t* wasm_memory_new(wasm_store_t* store, + const wasm_memorytype_t* type) { return release_memory(Memory::make(store, type)); } @@ -922,7 +924,6 @@ bool wasm_memory_grow(wasm_memory_t* memory, wasm_memory_pages_t delta) { return memory->grow(delta); } - // Externals WASM_DEFINE_REF(extern, Extern) @@ -977,41 +978,39 @@ wasm_memory_t* wasm_extern_as_memory(wasm_extern_t* external) { const wasm_func_t* wasm_extern_as_func_const(const wasm_extern_t* external) { return hide_func(external->func()); } -const wasm_global_t* wasm_extern_as_global_const(const wasm_extern_t* external) { +const wasm_global_t* wasm_extern_as_global_const( + const wasm_extern_t* external) { return hide_global(external->global()); } const wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t* external) { return hide_table(external->table()); } -const wasm_memory_t* wasm_extern_as_memory_const(const wasm_extern_t* external) { +const wasm_memory_t* wasm_extern_as_memory_const( + const wasm_extern_t* external) { return hide_memory(external->memory()); } - // Module Instances WASM_DEFINE_REF(instance, Instance) -wasm_instance_t* wasm_instance_new( - wasm_store_t* store, - const wasm_module_t* module, - const wasm_extern_t* const imports[], - wasm_trap_t** trap -) { +wasm_instance_t* wasm_instance_new(wasm_store_t* store, + const wasm_module_t* module, + const wasm_extern_t* const imports[], + wasm_trap_t** trap) { own error; - auto instance = release_instance(Instance::make(store, module, - reinterpret_cast(imports), &error)); - if (trap) *trap = hide_trap(error.release()); + auto instance = release_instance(Instance::make( + store, module, reinterpret_cast(imports), &error)); + if (trap) + *trap = hide_trap(error.release()); return instance; } -void wasm_instance_exports( - const wasm_instance_t* instance, wasm_extern_vec_t* out -) { +void wasm_instance_exports(const wasm_instance_t* instance, + wasm_extern_vec_t* out) { *out = release_extern_vec(instance->exports()); } - wasm_instance_t* wasm_frame_instance(const wasm_frame_t* frame) { return hide_instance(reveal_frame(frame)->instance()); } diff --git a/src/wasm-v8-lowlevel.cc b/src/wasm-v8-lowlevel.cc index d00f48e..1950e2b 100644 --- a/src/wasm-v8-lowlevel.cc +++ b/src/wasm-v8-lowlevel.cc @@ -1,28 +1,25 @@ #include "wasm-v8-lowlevel.hh" // TODO(v8): if we don't include these, api.h does not compile -#include "objects/objects.h" +#include "api/api-inl.h" +#include "api/api.h" #include "objects/bigint.h" +#include "objects/fixed-array.h" +#include "objects/js-collection.h" +#include "objects/js-promise.h" #include "objects/managed.h" #include "objects/module.h" +#include "objects/objects.h" +#include "objects/ordered-hash-table.h" #include "objects/shared-function-info.h" #include "objects/templates.h" -#include "objects/fixed-array.h" -#include "objects/ordered-hash-table.h" -#include "objects/js-promise.h" -#include "objects/js-collection.h" - -#include "api/api.h" -#include "api/api-inl.h" -#include "wasm/wasm-objects.h" #include "wasm/wasm-objects-inl.h" +#include "wasm/wasm-objects.h" #include "wasm/wasm-serialization.h" - namespace v8 { namespace wasm { - // Objects auto object_isolate(v8::Local obj) -> v8::Isolate* { @@ -31,17 +28,18 @@ auto object_isolate(v8::Local obj) -> v8::Isolate* { } auto object_isolate(const v8::Persistent& obj) -> v8::Isolate* { - struct FakePersistent { v8::Object* val; }; + struct FakePersistent { + v8::Object* val; + }; auto v8_obj = reinterpret_cast(&obj)->val; return v8_obj->GetIsolate(); } -template +template auto object_handle(T v8_obj) -> v8::internal::Handle { return handle(v8_obj, v8_obj.GetIsolate()); } - auto object_is_module(v8::Local obj) -> bool { auto v8_obj = v8::Utils::OpenHandle(*obj); return v8_obj->IsWasmModuleObject(); @@ -77,124 +75,157 @@ auto object_is_error(v8::Local obj) -> bool { return v8_obj->IsJSError(); } - - // Foreign pointers auto foreign_new(v8::Isolate* isolate, void* ptr) -> v8::Local { - auto foreign = v8::FromCData( - reinterpret_cast(isolate), - reinterpret_cast(ptr) - ); + auto foreign = + v8::FromCData(reinterpret_cast(isolate), + reinterpret_cast(ptr)); return v8::Utils::ToLocal(foreign); } auto foreign_get(v8::Local val) -> void* { auto foreign = v8::Utils::OpenHandle(*val); - if (!foreign->IsForeign()) return nullptr; + if (!foreign->IsForeign()) + return nullptr; auto addr = v8::ToCData(*foreign); return reinterpret_cast(addr); } - struct ManagedData { - ManagedData(void* info, void (*finalizer)(void*)) : - info(info), finalizer(finalizer) {} + ManagedData(void* info, void (*finalizer)(void*)) + : info(info), finalizer(finalizer) {} ~ManagedData() { - if (finalizer) (*finalizer)(info); + if (finalizer) + (*finalizer)(info); } void* info; void (*finalizer)(void*); }; -auto managed_new(v8::Isolate* isolate, void* ptr, void (*finalizer)(void*)) -> v8::Local { +auto managed_new(v8::Isolate* isolate, void* ptr, void (*finalizer)(void*)) + -> v8::Local { assert(ptr); auto managed = v8::internal::Managed::FromUniquePtr( - reinterpret_cast(isolate), sizeof(ManagedData), - std::unique_ptr(new ManagedData(ptr, finalizer)) - ); + reinterpret_cast(isolate), sizeof(ManagedData), + std::unique_ptr(new ManagedData(ptr, finalizer))); return v8::Utils::ToLocal(managed); } auto managed_get(v8::Local val) -> void* { auto v8_val = v8::Utils::OpenHandle(*val); - if (!v8_val->IsForeign()) return nullptr; + if (!v8_val->IsForeign()) + return nullptr; auto managed = - v8::internal::Handle>::cast(v8_val); + v8::internal::Handle>::cast(v8_val); return managed->raw()->info; } - // Types -auto v8_valtype_to_wasm(v8::internal::wasm::ValueType v8_valtype) -> val_kind_t { +auto v8_valtype_to_wasm(v8::internal::wasm::ValueType v8_valtype) + -> val_kind_t { switch (v8_valtype) { - case v8::internal::wasm::kWasmI32: return I32; - case v8::internal::wasm::kWasmI64: return I64; - case v8::internal::wasm::kWasmF32: return F32; - case v8::internal::wasm::kWasmF64: return F64; - case v8::internal::wasm::kWasmAnyRef: return ANYREF; - case v8::internal::wasm::kWasmAnyFunc: return FUNCREF; + case v8::internal::wasm::kWasmI32: + return I32; + case v8::internal::wasm::kWasmI64: + return I64; + case v8::internal::wasm::kWasmF32: + return F32; + case v8::internal::wasm::kWasmF64: + return F64; + case v8::internal::wasm::kWasmAnyRef: + return ANYREF; + case v8::internal::wasm::kWasmAnyFunc: + return FUNCREF; default: UNREACHABLE(); } } auto func_type_param_arity(v8::Local function) -> uint32_t { - auto v8_object = v8::Utils::OpenHandle(function); - auto v8_function = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(function); + auto v8_function = + v8::internal::Handle::cast(v8_object); v8::internal::wasm::FunctionSig* sig = - v8_function->instance().module()->functions[v8_function->function_index()].sig; + v8_function->instance() + .module() + ->functions[v8_function->function_index()] + .sig; return static_cast(sig->parameter_count()); } auto func_type_result_arity(v8::Local function) -> uint32_t { - auto v8_object = v8::Utils::OpenHandle(function); - auto v8_function = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(function); + auto v8_function = + v8::internal::Handle::cast(v8_object); v8::internal::wasm::FunctionSig* sig = - v8_function->instance().module()->functions[v8_function->function_index()].sig; + v8_function->instance() + .module() + ->functions[v8_function->function_index()] + .sig; return static_cast(sig->return_count()); } auto func_type_param(v8::Local function, size_t i) -> val_kind_t { - auto v8_object = v8::Utils::OpenHandle(function); - auto v8_function = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(function); + auto v8_function = + v8::internal::Handle::cast(v8_object); v8::internal::wasm::FunctionSig* sig = - v8_function->instance().module()->functions[v8_function->function_index()].sig; + v8_function->instance() + .module() + ->functions[v8_function->function_index()] + .sig; return v8_valtype_to_wasm(sig->GetParam(i)); } auto func_type_result(v8::Local function, size_t i) -> val_kind_t { - auto v8_object = v8::Utils::OpenHandle(function); - auto v8_function = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(function); + auto v8_function = + v8::internal::Handle::cast(v8_object); v8::internal::wasm::FunctionSig* sig = - v8_function->instance().module()->functions[v8_function->function_index()].sig; + v8_function->instance() + .module() + ->functions[v8_function->function_index()] + .sig; return v8_valtype_to_wasm(sig->GetReturn(i)); } auto global_type_content(v8::Local global) -> val_kind_t { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); return v8_valtype_to_wasm(v8_global->type()); } auto global_type_mutable(v8::Local global) -> bool { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); return v8_global->is_mutable(); } auto table_type_min(v8::Local table) -> uint32_t { - auto v8_object = v8::Utils::OpenHandle(table); - auto v8_table = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(table); + auto v8_table = + v8::internal::Handle::cast(v8_object); return v8_table->current_length(); } auto table_type_max(v8::Local table) -> uint32_t { - auto v8_object = v8::Utils::OpenHandle(table); - auto v8_table = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(table); + auto v8_table = + v8::internal::Handle::cast(v8_object); auto v8_max_obj = v8_table->maximum_length(); uint32_t max; return v8_max_obj.ToUint32(&max) ? max : 0xffffffffu; @@ -205,237 +236,304 @@ auto memory_type_min(v8::Local memory) -> uint32_t { } auto memory_type_max(v8::Local memory) -> uint32_t { - auto v8_object = v8::Utils::OpenHandle(memory); - auto v8_memory = v8::internal::Handle::cast(v8_object); - return v8_memory->has_maximum_pages() ? v8_memory->maximum_pages() : 0xffffffffu; + auto v8_object = + v8::Utils::OpenHandle(memory); + auto v8_memory = + v8::internal::Handle::cast(v8_object); + return v8_memory->has_maximum_pages() ? v8_memory->maximum_pages() + : 0xffffffffu; } - // Modules auto module_binary_size(v8::Local module) -> size_t { - auto v8_object = v8::Utils::OpenHandle(module); - auto v8_module = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(module); + auto v8_module = + v8::internal::Handle::cast(v8_object); return v8_module->native_module()->wire_bytes().size(); } auto module_binary(v8::Local module) -> const char* { - auto v8_object = v8::Utils::OpenHandle(module); - auto v8_module = v8::internal::Handle::cast(v8_object); - return reinterpret_cast(v8_module->native_module()->wire_bytes().begin()); + auto v8_object = + v8::Utils::OpenHandle(module); + auto v8_module = + v8::internal::Handle::cast(v8_object); + return reinterpret_cast( + v8_module->native_module()->wire_bytes().begin()); } auto module_serialize_size(v8::Local module) -> size_t { - auto v8_object = v8::Utils::OpenHandle(module); - auto v8_module = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(module); + auto v8_module = + v8::internal::Handle::cast(v8_object); v8::internal::wasm::WasmSerializer serializer(v8_module->native_module()); return serializer.GetSerializedNativeModuleSize(); } -auto module_serialize(v8::Local module, char* buffer, size_t size) -> bool { - auto v8_object = v8::Utils::OpenHandle(module); - auto v8_module = v8::internal::Handle::cast(v8_object); +auto module_serialize(v8::Local module, char* buffer, size_t size) + -> bool { + auto v8_object = + v8::Utils::OpenHandle(module); + auto v8_module = + v8::internal::Handle::cast(v8_object); v8::internal::wasm::WasmSerializer serializer(v8_module->native_module()); - return serializer.SerializeNativeModule({reinterpret_cast(buffer), size}); + return serializer.SerializeNativeModule( + {reinterpret_cast(buffer), size}); } -auto module_deserialize( - v8::Isolate* isolate, - const char* binary, size_t binary_size, - const char* buffer, size_t buffer_size -) -> v8::MaybeLocal { +auto module_deserialize(v8::Isolate* isolate, + const char* binary, + size_t binary_size, + const char* buffer, + size_t buffer_size) -> v8::MaybeLocal { auto v8_isolate = reinterpret_cast(isolate); - auto maybe_v8_module = - v8::internal::wasm::DeserializeNativeModule(v8_isolate, - {reinterpret_cast(buffer), buffer_size}, + auto maybe_v8_module = v8::internal::wasm::DeserializeNativeModule( + v8_isolate, {reinterpret_cast(buffer), buffer_size}, {reinterpret_cast(binary), binary_size}); - if (maybe_v8_module.is_null()) return v8::MaybeLocal(); - auto v8_module = v8::internal::Handle::cast(maybe_v8_module.ToHandleChecked()); + if (maybe_v8_module.is_null()) + return v8::MaybeLocal(); + auto v8_module = v8::internal::Handle::cast( + maybe_v8_module.ToHandleChecked()); return v8::MaybeLocal(v8::Utils::ToLocal(v8_module)); } - // Instances auto instance_module(v8::Local instance) -> v8::Local { - auto v8_object = v8::Utils::OpenHandle(instance); - auto v8_instance = v8::internal::Handle::cast(v8_object); - auto v8_module = object_handle(v8::internal::JSObject::cast(v8_instance->module_object())); + auto v8_object = + v8::Utils::OpenHandle(instance); + auto v8_instance = + v8::internal::Handle::cast(v8_object); + auto v8_module = + object_handle(v8::internal::JSObject::cast(v8_instance->module_object())); return v8::Utils::ToLocal(v8_module); } auto instance_exports(v8::Local instance) -> v8::Local { - auto v8_object = v8::Utils::OpenHandle(instance); - auto v8_instance = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(instance); + auto v8_instance = + v8::internal::Handle::cast(v8_object); auto v8_exports = object_handle(v8_instance->exports_object()); return v8::Utils::ToLocal(v8_exports); } - // Externals auto extern_kind(v8::Local external) -> extern_kind_t { - auto v8_object = v8::Utils::OpenHandle(external); - - if (v8::internal::WasmExportedFunction::IsWasmExportedFunction(*v8_object)) return EXTERN_FUNC; - if (v8_object->IsWasmGlobalObject()) return EXTERN_GLOBAL; - if (v8_object->IsWasmTableObject()) return EXTERN_TABLE; - if (v8_object->IsWasmMemoryObject()) return EXTERN_MEMORY; + auto v8_object = + v8::Utils::OpenHandle(external); + + if (v8::internal::WasmExportedFunction::IsWasmExportedFunction(*v8_object)) + return EXTERN_FUNC; + if (v8_object->IsWasmGlobalObject()) + return EXTERN_GLOBAL; + if (v8_object->IsWasmTableObject()) + return EXTERN_TABLE; + if (v8_object->IsWasmMemoryObject()) + return EXTERN_MEMORY; UNREACHABLE(); } - // Functions auto func_instance(v8::Local function) -> v8::Local { auto v8_function = v8::Utils::OpenHandle(*function); - auto v8_func = v8::internal::Handle::cast(v8_function); - auto v8_instance = object_handle(v8::internal::JSObject::cast(v8_func->instance())); + auto v8_func = v8::internal::Handle::cast( + v8_function); + auto v8_instance = + object_handle(v8::internal::JSObject::cast(v8_func->instance())); return v8::Utils::ToLocal(v8_instance); } - // Globals auto global_get_i32(v8::Local global) -> int32_t { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); return v8_global->GetI32(); } auto global_get_i64(v8::Local global) -> int64_t { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); return v8_global->GetI64(); } auto global_get_f32(v8::Local global) -> float { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); return v8_global->GetF32(); } auto global_get_f64(v8::Local global) -> double { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); return v8_global->GetF64(); } auto global_get_ref(v8::Local global) -> v8::Local { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); return v8::Utils::ToLocal(v8_global->GetRef()); } void global_set_i32(v8::Local global, int32_t val) { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); v8_global->SetI32(val); } void global_set_i64(v8::Local global, int64_t val) { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); v8_global->SetI64(val); } void global_set_f32(v8::Local global, float val) { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); v8_global->SetF32(val); } void global_set_f64(v8::Local global, double val) { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); v8_global->SetF64(val); } void global_set_ref(v8::Local global, v8::Local val) { - auto v8_object = v8::Utils::OpenHandle(global); - auto v8_global = v8::internal::Handle::cast(v8_object); - v8_global->SetAnyRef(v8::Utils::OpenHandle(val)); + auto v8_object = + v8::Utils::OpenHandle(global); + auto v8_global = + v8::internal::Handle::cast(v8_object); + v8_global->SetAnyRef( + v8::Utils::OpenHandle(val)); } - // Tables -auto table_get(v8::Local table, size_t index) -> v8::MaybeLocal { - auto v8_object = v8::Utils::OpenHandle(table); - auto v8_table = v8::internal::Handle::cast(v8_object); +auto table_get(v8::Local table, size_t index) + -> v8::MaybeLocal { + auto v8_object = + v8::Utils::OpenHandle(table); + auto v8_table = + v8::internal::Handle::cast(v8_object); // TODO(v8): This should happen in WasmTableObject::Get. - if (index > v8_table->current_length()) return v8::MaybeLocal(); + if (index > v8_table->current_length()) + return v8::MaybeLocal(); v8::internal::Handle v8_value = - v8::internal::WasmTableObject::Get( - v8_table->GetIsolate(), v8_table, static_cast(index)); - return v8::Utils::ToLocal(v8::internal::Handle::cast(v8_value)); -} - -auto table_set( - v8::Local table, size_t index, v8::Local value -) -> bool { - auto v8_object = v8::Utils::OpenHandle(table); - auto v8_table = v8::internal::Handle::cast(v8_object); + v8::internal::WasmTableObject::Get(v8_table->GetIsolate(), v8_table, + static_cast(index)); + return v8::Utils::ToLocal( + v8::internal::Handle::cast(v8_value)); +} + +auto table_set(v8::Local table, + size_t index, + v8::Local value) -> bool { + auto v8_object = + v8::Utils::OpenHandle(table); + auto v8_table = + v8::internal::Handle::cast(v8_object); auto v8_value = v8::Utils::OpenHandle(value); // TODO(v8): This should happen in WasmTableObject::Set. - if (index >= v8_table->current_length()) return false; + if (index >= v8_table->current_length()) + return false; - { v8::TryCatch handler(table->GetIsolate()); + { + v8::TryCatch handler(table->GetIsolate()); v8::internal::WasmTableObject::Set(v8_table->GetIsolate(), v8_table, - static_cast(index), v8_value); - if (handler.HasCaught()) return false; + static_cast(index), v8_value); + if (handler.HasCaught()) + return false; } return true; } auto table_size(v8::Local table) -> size_t { - auto v8_object = v8::Utils::OpenHandle(table); - auto v8_table = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(table); + auto v8_table = + v8::internal::Handle::cast(v8_object); return v8_table->current_length(); } -auto table_grow( - v8::Local table, size_t delta, v8::Local init -) -> bool { - auto v8_object = v8::Utils::OpenHandle(table); - auto v8_table = v8::internal::Handle::cast(v8_object); - if (delta > 0xfffffffflu) return false; +auto table_grow(v8::Local table, + size_t delta, + v8::Local init) -> bool { + auto v8_object = + v8::Utils::OpenHandle(table); + auto v8_table = + v8::internal::Handle::cast(v8_object); + if (delta > 0xfffffffflu) + return false; auto old_size = v8_table->current_length(); auto new_size = old_size + static_cast(delta); // TODO(v8): This should happen in WasmTableObject::Grow. - if (new_size > table_type_max(table)) return false; + if (new_size > table_type_max(table)) + return false; - { v8::TryCatch handler(table->GetIsolate()); + { + v8::TryCatch handler(table->GetIsolate()); v8::internal::WasmTableObject::Grow( - v8_table->GetIsolate(), v8_table, static_cast(delta), - v8::Utils::OpenHandle(init)); - if (handler.HasCaught()) return false; + v8_table->GetIsolate(), v8_table, static_cast(delta), + v8::Utils::OpenHandle(init)); + if (handler.HasCaught()) + return false; } return true; } - // Memory auto memory_data(v8::Local memory) -> char* { - auto v8_object = v8::Utils::OpenHandle(memory); - auto v8_memory = v8::internal::Handle::cast(v8_object); + auto v8_object = + v8::Utils::OpenHandle(memory); + auto v8_memory = + v8::internal::Handle::cast(v8_object); return reinterpret_cast(v8_memory->array_buffer().backing_store()); } -auto memory_data_size(v8::Local memory)-> size_t { - auto v8_object = v8::Utils::OpenHandle(memory); - auto v8_memory = v8::internal::Handle::cast(v8_object); +auto memory_data_size(v8::Local memory) -> size_t { + auto v8_object = + v8::Utils::OpenHandle(memory); + auto v8_memory = + v8::internal::Handle::cast(v8_object); return v8_memory->array_buffer().byte_length(); } auto memory_size(v8::Local memory) -> uint32_t { - auto v8_object = v8::Utils::OpenHandle(memory); - auto v8_memory = v8::internal::Handle::cast(v8_object); - return static_cast( - v8_memory->array_buffer().byte_length() / v8::internal::wasm::kWasmPageSize); + auto v8_object = + v8::Utils::OpenHandle(memory); + auto v8_memory = + v8::internal::Handle::cast(v8_object); + return static_cast(v8_memory->array_buffer().byte_length() / + v8::internal::wasm::kWasmPageSize); } auto memory_grow(v8::Local memory, uint32_t delta) -> bool { - auto v8_object = v8::Utils::OpenHandle(memory); - auto v8_memory = v8::internal::Handle::cast(v8_object); - auto old = v8::internal::WasmMemoryObject::Grow( - v8_memory->GetIsolate(), v8_memory, delta); + auto v8_object = + v8::Utils::OpenHandle(memory); + auto v8_memory = + v8::internal::Handle::cast(v8_object); + auto old = v8::internal::WasmMemoryObject::Grow(v8_memory->GetIsolate(), + v8_memory, delta); return old != -1; } diff --git a/src/wasm-v8-lowlevel.hh b/src/wasm-v8-lowlevel.hh index 5b2969f..8980cf0 100644 --- a/src/wasm-v8-lowlevel.hh +++ b/src/wasm-v8-lowlevel.hh @@ -42,7 +42,8 @@ auto module_binary_size(v8::Local module) -> size_t; auto module_binary(v8::Local module) -> const char*; auto module_serialize_size(v8::Local module) -> size_t; auto module_serialize(v8::Local module, char*, size_t) -> bool; -auto module_deserialize(v8::Isolate*, const char*, size_t, const char*, size_t) -> v8::MaybeLocal; +auto module_deserialize(v8::Isolate*, const char*, size_t, const char*, size_t) + -> v8::MaybeLocal; auto instance_module(v8::Local instance) -> v8::Local; auto instance_exports(v8::Local instance) -> v8::Local; @@ -63,13 +64,16 @@ void global_set_f32(v8::Local global, float); void global_set_f64(v8::Local global, double); void global_set_ref(v8::Local global, v8::Local); -auto table_get(v8::Local table, size_t index) -> v8::MaybeLocal; -auto table_set(v8::Local table, size_t index, v8::Local) -> bool; +auto table_get(v8::Local table, size_t index) + -> v8::MaybeLocal; +auto table_set(v8::Local table, size_t index, v8::Local) + -> bool; auto table_size(v8::Local table) -> size_t; -auto table_grow(v8::Local table, size_t delta, v8::Local) -> bool; +auto table_grow(v8::Local table, size_t delta, v8::Local) + -> bool; auto memory_data(v8::Local memory) -> char*; -auto memory_data_size(v8::Local memory)-> size_t; +auto memory_data_size(v8::Local memory) -> size_t; auto memory_size(v8::Local memory) -> uint32_t; auto memory_grow(v8::Local memory, uint32_t delta) -> bool; diff --git a/src/wasm-v8.cc b/src/wasm-v8.cc index 5f06ab0..3acd3e3 100644 --- a/src/wasm-v8.cc +++ b/src/wasm-v8.cc @@ -1,31 +1,29 @@ -#include "wasm.hh" -#include "wasm-bin.hh" -#include "wasm-v8-lowlevel.hh" +#include -#include "v8.h" #include "libplatform/libplatform.h" - -#include +#include "v8.h" +#include "wasm-bin.hh" +#include "wasm-v8-lowlevel.hh" +#include "wasm.hh" #ifdef WASM_API_DEBUG #include #endif - namespace wasm_v8 { - using namespace v8::wasm; +using namespace v8::wasm; } namespace v8 { - namespace internal { - extern bool FLAG_expose_gc; - extern bool FLAG_experimental_wasm_bigint; - extern bool FLAG_experimental_wasm_mv; - extern bool FLAG_experimental_wasm_anyref; - extern bool FLAG_experimental_wasm_bulk_memory; - extern bool FLAG_experimental_wasm_return_call; - } -} +namespace internal { +extern bool FLAG_expose_gc; +extern bool FLAG_experimental_wasm_bigint; +extern bool FLAG_experimental_wasm_mv; +extern bool FLAG_experimental_wasm_anyref; +extern bool FLAG_experimental_wasm_bulk_memory; +extern bool FLAG_experimental_wasm_return_call; +} // namespace internal +} // namespace v8 namespace wasm { @@ -37,50 +35,66 @@ namespace wasm { exit(1); } -template +template void ignore(T) {} +template +struct implement; -template struct implement; - -template -auto impl(C* x) -> typename implement ::type* { +template +auto impl(C* x) -> typename implement::type* { return reinterpret_cast::type*>(x); } -template +template auto impl(const C* x) -> const typename implement::type* { return reinterpret_cast::type*>(x); } -template -auto seal(typename implement ::type* x) -> C* { +template +auto seal(typename implement::type* x) -> C* { return reinterpret_cast(x); } -template -auto seal(const typename implement ::type* x) -> const C* { +template +auto seal(const typename implement::type* x) -> const C* { return reinterpret_cast(x); } - /////////////////////////////////////////////////////////////////////////////// // Debug aids struct Stats { enum category_t { - BYTE, CONFIG, ENGINE, STORE, FRAME, - VALTYPE, FUNCTYPE, GLOBALTYPE, TABLETYPE, MEMORYTYPE, - EXTERNTYPE, IMPORTTYPE, EXPORTTYPE, - VAL, REF, TRAP, - MODULE, INSTANCE, FUNC, GLOBAL, TABLE, MEMORY, EXTERN, + BYTE, + CONFIG, + ENGINE, + STORE, + FRAME, + VALTYPE, + FUNCTYPE, + GLOBALTYPE, + TABLETYPE, + MEMORYTYPE, + EXTERNTYPE, + IMPORTTYPE, + EXPORTTYPE, + VAL, + REF, + TRAP, + MODULE, + INSTANCE, + FUNC, + GLOBAL, + TABLE, + MEMORY, + EXTERN, STRONG_COUNT, - FUNCDATA_FUNCTYPE, FUNCDATA_VALTYPE, + FUNCDATA_FUNCTYPE, + FUNCDATA_VALTYPE, CATEGORY_COUNT }; - enum cardinality_t { - OWN, VEC, SHARED, CARDINALITY_COUNT - }; + enum cardinality_t { OWN, VEC, SHARED, CARDINALITY_COUNT }; #ifdef WASM_API_DEBUG static const char* name[STRONG_COUNT]; @@ -101,11 +115,11 @@ struct Stats { ~Stats() { // Hack for func data weakly owned by V8 heap. freed[FUNCTYPE][OWN] += - made[FUNCDATA_FUNCTYPE][OWN] - freed[FUNCDATA_FUNCTYPE][OWN]; + made[FUNCDATA_FUNCTYPE][OWN] - freed[FUNCDATA_FUNCTYPE][OWN]; freed[VALTYPE][OWN] += - made[FUNCDATA_VALTYPE][OWN] - freed[FUNCDATA_VALTYPE][OWN]; + made[FUNCDATA_VALTYPE][OWN] - freed[FUNCDATA_VALTYPE][OWN]; freed[VALTYPE][VEC] += - made[FUNCDATA_VALTYPE][VEC] - freed[FUNCDATA_VALTYPE][VEC]; + made[FUNCDATA_VALTYPE][VEC] - freed[FUNCDATA_VALTYPE][VEC]; // Hack for shared modules. freed[BYTE][VEC] += made[MODULE][SHARED] - freed[MODULE][SHARED]; @@ -115,15 +129,15 @@ struct Stats { assert(made[i][j] >= freed[i][j]); auto live = made[i][j] - freed[i][j]; if (live) { - std::cerr << "Leaked " << live << " instances of wasm::" - << left[j] << name[i] << right[j] - << ", made " << made[i][j] << ", freed " << freed[i][j] << "!" - << std::endl; + std::cerr << "Leaked " << live << " instances of wasm::" << left[j] + << name[i] << right[j] << ", made " << made[i][j] + << ", freed " << freed[i][j] << "!" << std::endl; leak = true; } } } - if (leak) exit(1); + if (leak) + exit(1); } #endif @@ -131,8 +145,8 @@ struct Stats { #ifdef WASM_API_DEBUG #ifdef WASM_API_DEBUG_LOG if (ptr) { - std::clog << "[make] " << ptr - << " wasm::" << left[j] << name[i] << right[j] << std::endl; + std::clog << "[make] " << ptr << " wasm::" << left[j] << name[i] + << right[j] << std::endl; } #endif made[i][j] += n; @@ -143,16 +157,16 @@ struct Stats { #ifdef WASM_API_DEBUG #ifdef WASM_API_DEBUG_LOG if (ptr) { - std::clog << "[free] " << ptr - << " wasm::" << left[j] << name[i] << right[j] << std::endl; + std::clog << "[free] " << ptr << " wasm::" << left[j] << name[i] + << right[j] << std::endl; } #endif freed[i][j] += n; if (freed[i][j] > made[i][j]) { - std::cerr << "Deleting instance of wasm::" - << left[j] << name[i] << right[j] << " when none is alive" - << ", made " << made[i][j] << ", freed " << freed[i][j] << "!" - << std::endl; + std::cerr << "Deleting instance of wasm::" << left[j] << name[i] + << right[j] << " when none is alive" + << ", made " << made[i][j] << ", freed " << freed[i][j] << "!" + << std::endl; exit(1); } #endif @@ -163,13 +177,20 @@ struct Stats { auto isolate = wasm_v8::object_isolate(pobj); v8::HandleScope handle_scope(isolate); auto obj = pobj.Get(isolate); - if (wasm_v8::object_is_func(obj)) return FUNC; - if (wasm_v8::object_is_global(obj)) return GLOBAL; - if (wasm_v8::object_is_table(obj)) return TABLE; - if (wasm_v8::object_is_memory(obj)) return MEMORY; - if (wasm_v8::object_is_module(obj)) return MODULE; - if (wasm_v8::object_is_instance(obj)) return INSTANCE; - if (wasm_v8::object_is_error(obj)) return TRAP; + if (wasm_v8::object_is_func(obj)) + return FUNC; + if (wasm_v8::object_is_global(obj)) + return GLOBAL; + if (wasm_v8::object_is_table(obj)) + return TABLE; + if (wasm_v8::object_is_memory(obj)) + return MEMORY; + if (wasm_v8::object_is_module(obj)) + return MODULE; + if (wasm_v8::object_is_instance(obj)) + return INSTANCE; + if (wasm_v8::object_is_error(obj)) + return TRAP; #endif return REF; } @@ -177,37 +198,34 @@ struct Stats { #ifdef WASM_API_DEBUG const char* Stats::name[STRONG_COUNT] = { - "byte_t", "Config", "Engine", "Store", "Frame", - "ValType", "FuncType", "GlobalType", "TableType", "MemoryType", - "ExternType", "ImportType", "ExportType", - "Val", "Ref", "Trap", - "Module", "Instance", "Func", "Global", "Table", "Memory", "Extern" -}; + "byte_t", "Config", "Engine", "Store", "Frame", + "ValType", "FuncType", "GlobalType", "TableType", "MemoryType", + "ExternType", "ImportType", "ExportType", "Val", "Ref", + "Trap", "Module", "Instance", "Func", "Global", + "Table", "Memory", "Extern"}; -const char* Stats::left[CARDINALITY_COUNT] = { - "", "vec<", "Shared<" -}; +const char* Stats::left[CARDINALITY_COUNT] = {"", "vec<", "Shared<"}; -const char* Stats::right[CARDINALITY_COUNT] = { - "", ">", ">" -}; +const char* Stats::right[CARDINALITY_COUNT] = {"", ">", ">"}; #endif - Stats stats; - // Vectors #ifdef WASM_API_DEBUG -#define DEFINE_VEC(type, vec, STAT) \ - template<> void vec::make_data() { \ - if (data_) stats.make(Stats::STAT, data_.get(), Stats::VEC); \ - } \ - \ - template<> void vec::free_data() { \ - if (data_) stats.free(Stats::STAT, data_.get(), Stats::VEC); \ +#define DEFINE_VEC(type, vec, STAT) \ + template <> \ + void vec::make_data() { \ + if (data_) \ + stats.make(Stats::STAT, data_.get(), Stats::VEC); \ + } \ + \ + template <> \ + void vec::free_data() { \ + if (data_) \ + stats.free(Stats::STAT, data_.get(), Stats::VEC); \ } DEFINE_VEC(byte_t, vec, BYTE) @@ -233,7 +251,6 @@ DEFINE_VEC(Val, vec, VAL) #endif // #ifdef WASM_API_DEBUG - /////////////////////////////////////////////////////////////////////////////// // Runtime Environment @@ -244,22 +261,23 @@ struct ConfigImpl { ~ConfigImpl() { stats.free(Stats::CONFIG, this); } }; -template<> struct implement { using type = ConfigImpl; }; - +template <> +struct implement { + using type = ConfigImpl; +}; Config::~Config() { impl(this)->~ConfigImpl(); } -void Config::operator delete(void *p) { +void Config::operator delete(void* p) { ::operator delete(p); } auto Config::make() -> own { - return own(seal(new(std::nothrow) ConfigImpl())); + return own(seal(new (std::nothrow) ConfigImpl())); } - // Engine struct EngineImpl { @@ -282,14 +300,16 @@ struct EngineImpl { bool EngineImpl::created = false; -template<> struct implement { using type = EngineImpl; }; - +template <> +struct implement { + using type = EngineImpl; +}; Engine::~Engine() { impl(this)->~EngineImpl(); } -void Engine::operator delete(void *p) { +void Engine::operator delete(void* p) { ::operator delete(p); } @@ -301,8 +321,9 @@ auto Engine::make(own&& config) -> own { v8::internal::FLAG_experimental_wasm_bulk_memory = true; v8::internal::FLAG_experimental_wasm_return_call = true; // v8::V8::SetFlagsFromCommandLine(&argc, const_cast(argv), false); - auto engine = new(std::nothrow) EngineImpl; - if (!engine) return own(); + auto engine = new (std::nothrow) EngineImpl; + if (!engine) + return own(); // v8::V8::InitializeICUDefaultLocation(argv[0]); // v8::V8::InitializeExternalStartupData(argv[0]); engine->platform = v8::platform::NewDefaultPlatform(); @@ -311,25 +332,37 @@ auto Engine::make(own&& config) -> own { return make_own(seal(engine)); } - // Stores enum v8_string_t { V8_S_EMPTY, - V8_S_I32, V8_S_I64, V8_S_F32, V8_S_F64, V8_S_ANYREF, V8_S_ANYFUNC, - V8_S_VALUE, V8_S_MUTABLE, V8_S_ELEMENT, V8_S_MINIMUM, V8_S_MAXIMUM, + V8_S_I32, + V8_S_I64, + V8_S_F32, + V8_S_F64, + V8_S_ANYREF, + V8_S_ANYFUNC, + V8_S_VALUE, + V8_S_MUTABLE, + V8_S_ELEMENT, + V8_S_MINIMUM, + V8_S_MAXIMUM, V8_S_COUNT }; -enum v8_symbol_t { - V8_Y_CALLBACK, V8_Y_ENV, - V8_Y_COUNT -}; +enum v8_symbol_t { V8_Y_CALLBACK, V8_Y_ENV, V8_Y_COUNT }; enum v8_function_t { - V8_F_WEAKMAP, V8_F_WEAKMAP_PROTO, V8_F_WEAKMAP_GET, V8_F_WEAKMAP_SET, - V8_F_MODULE, V8_F_GLOBAL, V8_F_TABLE, V8_F_MEMORY, - V8_F_INSTANCE, V8_F_VALIDATE, + V8_F_WEAKMAP, + V8_F_WEAKMAP_PROTO, + V8_F_WEAKMAP_GET, + V8_F_WEAKMAP_SET, + V8_F_MODULE, + V8_F_GLOBAL, + V8_F_TABLE, + V8_F_MEMORY, + V8_F_INSTANCE, + V8_F_VALIDATE, V8_F_COUNT, }; @@ -337,7 +370,7 @@ class StoreImpl { friend own Store::make(Engine*); v8::Isolate::CreateParams create_params_; - v8::Isolate *isolate_; + v8::Isolate* isolate_; v8::Eternal context_; v8::Eternal strings_[V8_S_COUNT]; v8::Eternal symbols_[V8_Y_COUNT]; @@ -346,22 +379,20 @@ class StoreImpl { v8::Eternal callback_symbol_; v8::Persistent* handle_pool_ = nullptr; // TODO: use v8::Value -public: - StoreImpl() { - stats.make(Stats::STORE, this); - } + public: + StoreImpl() { stats.make(Stats::STORE, this); } ~StoreImpl() { #ifdef WASM_API_DEBUG isolate_->RequestGarbageCollectionForTesting( - v8::Isolate::kFullGarbageCollection); + v8::Isolate::kFullGarbageCollection); #endif { v8::HandleScope scope(isolate_); while (handle_pool_ != nullptr) { auto handle = handle_pool_; handle_pool_ = reinterpret_cast*>( - wasm_v8::foreign_get(handle->Get(isolate_))); + wasm_v8::foreign_get(handle->Get(isolate_))); delete handle; } } @@ -372,9 +403,7 @@ class StoreImpl { stats.free(Stats::STORE, this); } - auto isolate() const -> v8::Isolate* { - return isolate_; - } + auto isolate() const -> v8::Isolate* { return isolate_; } auto context() const -> v8::Local { return context_.Get(isolate_); @@ -403,14 +432,15 @@ class StoreImpl { static const size_t n = 100; for (size_t i = 0; i < n; ++i) { auto v8_next = wasm_v8::foreign_new(isolate_, handle_pool_); - handle_pool_ = new(std::nothrow) v8::Persistent(); - if (!handle_pool_) return nullptr; + handle_pool_ = new (std::nothrow) v8::Persistent(); + if (!handle_pool_) + return nullptr; handle_pool_->Reset(isolate_, v8::Local::Cast(v8_next)); } } auto handle = handle_pool_; handle_pool_ = reinterpret_cast*>( - wasm_v8::foreign_get(handle->Get(isolate_))); + wasm_v8::foreign_get(handle->Get(isolate_))); return handle; } @@ -422,26 +452,30 @@ class StoreImpl { } }; -template<> struct implement { using type = StoreImpl; }; - +template <> +struct implement { + using type = StoreImpl; +}; Store::~Store() { impl(this)->~StoreImpl(); } -void Store::operator delete(void *p) { +void Store::operator delete(void* p) { ::operator delete(p); } auto Store::make(Engine*) -> own { - auto store = make_own(new(std::nothrow) StoreImpl()); - if (!store) return own(); + auto store = make_own(new (std::nothrow) StoreImpl()); + if (!store) + return own(); // Create isolate. store->create_params_.array_buffer_allocator = - v8::ArrayBuffer::Allocator::NewDefaultAllocator(); + v8::ArrayBuffer::Allocator::NewDefaultAllocator(); auto isolate = v8::Isolate::New(store->create_params_); - if (!isolate) return own(); + if (!isolate) + return own(); { v8::Isolate::Scope isolate_scope(isolate); @@ -449,7 +483,8 @@ auto Store::make(Engine*) -> own { // Create context. auto context = v8::Context::New(isolate); - if (context.IsEmpty()) return own(); + if (context.IsEmpty()) + return own(); v8::Context::Scope context_scope(context); store->isolate_ = isolate; @@ -457,14 +492,14 @@ auto Store::make(Engine*) -> own { // Create strings. static const char* const raw_strings[V8_S_COUNT] = { - "", - "i32", "i64", "f32", "f64", "anyref", "anyfunc", - "value", "mutable", "element", "initial", "maximum", + "", "i32", "i64", "f32", "f64", "anyref", + "anyfunc", "value", "mutable", "element", "initial", "maximum", }; for (int i = 0; i < V8_S_COUNT; ++i) { auto maybe = v8::String::NewFromUtf8(isolate, raw_strings[i], - v8::NewStringType::kNormal); - if (maybe.IsEmpty()) return own(); + v8::NewStringType::kNormal); + if (maybe.IsEmpty()) + return own(); auto string = maybe.ToLocalChecked(); store->strings_[i] = v8::Eternal(isolate, string); } @@ -477,11 +512,13 @@ auto Store::make(Engine*) -> own { // Extract functions. auto global = context->Global(); auto maybe_wasm_name = v8::String::NewFromUtf8(isolate, "WebAssembly", - v8::NewStringType::kNormal); - if (maybe_wasm_name.IsEmpty()) return own(); + v8::NewStringType::kNormal); + if (maybe_wasm_name.IsEmpty()) + return own(); auto wasm_name = maybe_wasm_name.ToLocalChecked(); auto maybe_wasm = global->Get(context, wasm_name); - if (maybe_wasm.IsEmpty()) return own(); + if (maybe_wasm.IsEmpty()) + return own(); auto wasm = v8::Local::Cast(maybe_wasm.ToLocalChecked()); v8::Local weakmap; v8::Local weakmap_proto; @@ -490,21 +527,25 @@ auto Store::make(Engine*) -> own { const char* name; v8::Local* carrier; } raw_functions[V8_F_COUNT] = { - {"WeakMap", &global}, {"prototype", &weakmap}, - {"get", &weakmap_proto}, {"set", &weakmap_proto}, - {"Module", &wasm}, {"Global", &wasm}, {"Table", &wasm}, {"Memory", &wasm}, - {"Instance", &wasm}, {"validate", &wasm}, + {"WeakMap", &global}, {"prototype", &weakmap}, + {"get", &weakmap_proto}, {"set", &weakmap_proto}, + {"Module", &wasm}, {"Global", &wasm}, + {"Table", &wasm}, {"Memory", &wasm}, + {"Instance", &wasm}, {"validate", &wasm}, }; for (int i = 0; i < V8_F_COUNT; ++i) { auto maybe_name = v8::String::NewFromUtf8(isolate, raw_functions[i].name, - v8::NewStringType::kNormal); - if (maybe_name.IsEmpty()) return own(); + v8::NewStringType::kNormal); + if (maybe_name.IsEmpty()) + return own(); auto name = maybe_name.ToLocalChecked(); assert(!raw_functions[i].carrier->IsEmpty()); // TODO(wasm+): remove - if ((*raw_functions[i].carrier)->IsUndefined()) continue; + if ((*raw_functions[i].carrier)->IsUndefined()) + continue; auto maybe_obj = (*raw_functions[i].carrier)->Get(context, name); - if (maybe_obj.IsEmpty()) return own(); + if (maybe_obj.IsEmpty()) + return own(); auto obj = v8::Local::Cast(maybe_obj.ToLocalChecked()); if (i == V8_F_WEAKMAP_PROTO) { assert(obj->IsObject()); @@ -513,15 +554,17 @@ auto Store::make(Engine*) -> own { assert(obj->IsFunction()); auto function = v8::Local::Cast(obj); store->functions_[i] = v8::Eternal(isolate, function); - if (i == V8_F_WEAKMAP) weakmap = function; + if (i == V8_F_WEAKMAP) + weakmap = function; } } // Create host data weak map. v8::Local empty_args[] = {}; auto maybe_weakmap = - store->v8_function(V8_F_WEAKMAP)->NewInstance(context, 0, empty_args); - if (maybe_weakmap.IsEmpty()) return own(); + store->v8_function(V8_F_WEAKMAP)->NewInstance(context, 0, empty_args); + if (maybe_weakmap.IsEmpty()) + return own(); auto map = v8::Local::Cast(maybe_weakmap.ToLocalChecked()); assert(map->IsWeakMap()); store->host_data_map_ = v8::Eternal(isolate, map); @@ -534,7 +577,6 @@ auto Store::make(Engine*) -> own { return make_own(seal(store.release())); }; - /////////////////////////////////////////////////////////////////////////////// // Type Representations @@ -546,7 +588,10 @@ struct ValTypeImpl { ValTypeImpl(ValKind kind) : kind(kind) {} }; -template<> struct implement { using type = ValTypeImpl; }; +template <> +struct implement { + using type = ValTypeImpl; +}; ValTypeImpl* valtype_i32 = new ValTypeImpl(I32); ValTypeImpl* valtype_i64 = new ValTypeImpl(I64); @@ -555,7 +600,6 @@ ValTypeImpl* valtype_f64 = new ValTypeImpl(F64); ValTypeImpl* valtype_anyref = new ValTypeImpl(ANYREF); ValTypeImpl* valtype_funcref = new ValTypeImpl(FUNCREF); - ValType::~ValType() { stats.free(Stats::VALTYPE, this); } @@ -565,12 +609,24 @@ void ValType::operator delete(void*) {} auto ValType::make(ValKind k) -> own { ValTypeImpl* valtype; switch (k) { - case I32: valtype = valtype_i32; break; - case I64: valtype = valtype_i64; break; - case F32: valtype = valtype_f32; break; - case F64: valtype = valtype_f64; break; - case ANYREF: valtype = valtype_anyref; break; - case FUNCREF: valtype = valtype_funcref; break; + case I32: + valtype = valtype_i32; + break; + case I64: + valtype = valtype_i64; + break; + case F32: + valtype = valtype_f32; + break; + case F64: + valtype = valtype_f64; + break; + case ANYREF: + valtype = valtype_anyref; + break; + case FUNCREF: + valtype = valtype_funcref; + break; default: // TODO(wasm+): support new value types assert(false); @@ -588,7 +644,6 @@ auto ValType::kind() const -> ValKind { return impl(this)->kind; } - // Extern Types struct ExternTypeImpl { @@ -598,23 +653,29 @@ struct ExternTypeImpl { virtual ~ExternTypeImpl() {} }; -template<> struct implement { using type = ExternTypeImpl; }; - +template <> +struct implement { + using type = ExternTypeImpl; +}; ExternType::~ExternType() { impl(this)->~ExternTypeImpl(); } -void ExternType::operator delete(void *p) { +void ExternType::operator delete(void* p) { ::operator delete(p); } auto ExternType::copy() const -> own { switch (kind()) { - case EXTERN_FUNC: return func()->copy(); - case EXTERN_GLOBAL: return global()->copy(); - case EXTERN_TABLE: return table()->copy(); - case EXTERN_MEMORY: return memory()->copy(); + case EXTERN_FUNC: + return func()->copy(); + case EXTERN_GLOBAL: + return global()->copy(); + case EXTERN_TABLE: + return table()->copy(); + case EXTERN_MEMORY: + return memory()->copy(); } } @@ -622,36 +683,35 @@ auto ExternType::kind() const -> ExternKind { return impl(this)->kind; } - // Function Types struct FuncTypeImpl : ExternTypeImpl { ownvec params; ownvec results; - FuncTypeImpl(ownvec& params, ownvec& results) : - ExternTypeImpl(EXTERN_FUNC), - params(std::move(params)), results(std::move(results)) - { + FuncTypeImpl(ownvec& params, ownvec& results) + : ExternTypeImpl(EXTERN_FUNC), + params(std::move(params)), + results(std::move(results)) { stats.make(Stats::FUNCTYPE, this); } - ~FuncTypeImpl() { - stats.free(Stats::FUNCTYPE, this); - } + ~FuncTypeImpl() { stats.free(Stats::FUNCTYPE, this); } }; -template<> struct implement { using type = FuncTypeImpl; }; - +template <> +struct implement { + using type = FuncTypeImpl; +}; FuncType::~FuncType() {} auto FuncType::make(ownvec&& params, ownvec&& results) - -> own { + -> own { return params && results - ? own( - seal(new(std::nothrow) FuncTypeImpl(params, results))) - : own(); + ? own(seal(new (std::nothrow) + FuncTypeImpl(params, results))) + : own(); } auto FuncType::copy() const -> own { @@ -666,50 +726,46 @@ auto FuncType::results() const -> const ownvec& { return impl(this)->results; } - auto ExternType::func() -> FuncType* { return kind() == EXTERN_FUNC - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } auto ExternType::func() const -> const FuncType* { return kind() == EXTERN_FUNC - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } - // Global Types struct GlobalTypeImpl : ExternTypeImpl { own content; Mutability mutability; - GlobalTypeImpl(own& content, Mutability mutability) : - ExternTypeImpl(EXTERN_GLOBAL), - content(std::move(content)), mutability(mutability) - { + GlobalTypeImpl(own& content, Mutability mutability) + : ExternTypeImpl(EXTERN_GLOBAL), + content(std::move(content)), + mutability(mutability) { stats.make(Stats::GLOBALTYPE, this); } - ~GlobalTypeImpl() { - stats.free(Stats::GLOBALTYPE, this); - } + ~GlobalTypeImpl() { stats.free(Stats::GLOBALTYPE, this); } }; -template<> struct implement { using type = GlobalTypeImpl; }; - +template <> +struct implement { + using type = GlobalTypeImpl; +}; GlobalType::~GlobalType() {} -auto GlobalType::make( - own&& content, Mutability mutability -) -> own { - return content - ? own( - seal(new(std::nothrow) GlobalTypeImpl(content, mutability))) - : own(); +auto GlobalType::make(own&& content, Mutability mutability) + -> own { + return content ? own(seal( + new (std::nothrow) GlobalTypeImpl(content, mutability))) + : own(); } auto GlobalType::copy() const -> own { @@ -724,47 +780,45 @@ auto GlobalType::mutability() const -> Mutability { return impl(this)->mutability; } - auto ExternType::global() -> GlobalType* { return kind() == EXTERN_GLOBAL - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } auto ExternType::global() const -> const GlobalType* { return kind() == EXTERN_GLOBAL - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } - // Table Types struct TableTypeImpl : ExternTypeImpl { own element; Limits limits; - TableTypeImpl(own& element, Limits limits) : - ExternTypeImpl(EXTERN_TABLE), element(std::move(element)), limits(limits) - { + TableTypeImpl(own& element, Limits limits) + : ExternTypeImpl(EXTERN_TABLE), + element(std::move(element)), + limits(limits) { stats.make(Stats::TABLETYPE, this); } - ~TableTypeImpl() { - stats.free(Stats::TABLETYPE, this); - } + ~TableTypeImpl() { stats.free(Stats::TABLETYPE, this); } }; -template<> struct implement { using type = TableTypeImpl; }; - +template <> +struct implement { + using type = TableTypeImpl; +}; TableType::~TableType() {} auto TableType::make(own&& element, Limits limits) -> own { - return element - ? own( - seal(new(std::nothrow) TableTypeImpl(element, limits))) - : own(); + return element ? own(seal( + new (std::nothrow) TableTypeImpl(element, limits))) + : own(); } auto TableType::copy() const -> own { @@ -779,44 +833,41 @@ auto TableType::limits() const -> const Limits& { return impl(this)->limits; } - auto ExternType::table() -> TableType* { return kind() == EXTERN_TABLE - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } auto ExternType::table() const -> const TableType* { return kind() == EXTERN_TABLE - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } - // Memory Types struct MemoryTypeImpl : ExternTypeImpl { Limits limits; - MemoryTypeImpl(Limits limits) : - ExternTypeImpl(EXTERN_MEMORY), limits(limits) - { + MemoryTypeImpl(Limits limits) + : ExternTypeImpl(EXTERN_MEMORY), limits(limits) { stats.make(Stats::MEMORYTYPE, this); } - ~MemoryTypeImpl() { - stats.free(Stats::MEMORYTYPE, this); - } + ~MemoryTypeImpl() { stats.free(Stats::MEMORYTYPE, this); } }; -template<> struct implement { using type = MemoryTypeImpl; }; - +template <> +struct implement { + using type = MemoryTypeImpl; +}; MemoryType::~MemoryType() {} auto MemoryType::make(Limits limits) -> own { return own( - seal(new(std::nothrow) MemoryTypeImpl(limits))); + seal(new (std::nothrow) MemoryTypeImpl(limits))); } auto MemoryType::copy() const -> own { @@ -827,20 +878,18 @@ auto MemoryType::limits() const -> const Limits& { return impl(this)->limits; } - auto ExternType::memory() -> MemoryType* { return kind() == EXTERN_MEMORY - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } auto ExternType::memory() const -> const MemoryType* { return kind() == EXTERN_MEMORY - ? seal(static_cast(impl(this))) - : nullptr; + ? seal(static_cast(impl(this))) + : nullptr; } - // Import Types struct ImportTypeImpl { @@ -848,35 +897,35 @@ struct ImportTypeImpl { Name name; own type; - ImportTypeImpl(Name& module, Name& name, own& type) : - module(std::move(module)), name(std::move(name)), type(std::move(type)) - { + ImportTypeImpl(Name& module, Name& name, own& type) + : module(std::move(module)), + name(std::move(name)), + type(std::move(type)) { stats.make(Stats::IMPORTTYPE, this); } - ~ImportTypeImpl() { - stats.free(Stats::IMPORTTYPE, this); - } + ~ImportTypeImpl() { stats.free(Stats::IMPORTTYPE, this); } }; -template<> struct implement { using type = ImportTypeImpl; }; - +template <> +struct implement { + using type = ImportTypeImpl; +}; ImportType::~ImportType() { impl(this)->~ImportTypeImpl(); } -void ImportType::operator delete(void *p) { +void ImportType::operator delete(void* p) { ::operator delete(p); } -auto ImportType::make( - Name&& module, Name&& name, own&& type -) -> own { +auto ImportType::make(Name&& module, Name&& name, own&& type) + -> own { return module && name && type - ? own( - seal(new(std::nothrow) ImportTypeImpl(module, name, type))) - : own(); + ? own(seal( + new (std::nothrow) ImportTypeImpl(module, name, type))) + : own(); } auto ImportType::copy() const -> own { @@ -895,42 +944,37 @@ auto ImportType::type() const -> const ExternType* { return impl(this)->type.get(); } - // Export Types struct ExportTypeImpl { Name name; own type; - ExportTypeImpl(Name& name, own& type) : - name(std::move(name)), type(std::move(type)) - { + ExportTypeImpl(Name& name, own& type) + : name(std::move(name)), type(std::move(type)) { stats.make(Stats::EXPORTTYPE, this); } - ~ExportTypeImpl() { - stats.free(Stats::EXPORTTYPE, this); - } + ~ExportTypeImpl() { stats.free(Stats::EXPORTTYPE, this); } }; -template<> struct implement { using type = ExportTypeImpl; }; - +template <> +struct implement { + using type = ExportTypeImpl; +}; ExportType::~ExportType() { impl(this)->~ExportTypeImpl(); } -void ExportType::operator delete(void *p) { +void ExportType::operator delete(void* p) { ::operator delete(p); } -auto ExportType::make( - Name&& name, own&& type -) -> own { - return name && type - ? own( - seal(new(std::nothrow) ExportTypeImpl(name, type))) - : own(); +auto ExportType::make(Name&& name, own&& type) -> own { + return name && type ? own(seal( + new (std::nothrow) ExportTypeImpl(name, type))) + : own(); } auto ExportType::copy() const -> own { @@ -945,23 +989,33 @@ auto ExportType::type() const -> const ExternType* { return impl(this)->type.get(); } - /////////////////////////////////////////////////////////////////////////////// // Conversions of types from and to V8 objects // Types -auto valtype_to_v8( - StoreImpl* store, const ValType* type -) -> v8::Local { +auto valtype_to_v8(StoreImpl* store, const ValType* type) + -> v8::Local { v8_string_t string; switch (type->kind()) { - case I32: string = V8_S_I32; break; - case I64: string = V8_S_I64; break; - case F32: string = V8_S_F32; break; - case F64: string = V8_S_F64; break; - case ANYREF: string = V8_S_ANYREF; break; - case FUNCREF: string = V8_S_ANYFUNC; break; + case I32: + string = V8_S_I32; + break; + case I64: + string = V8_S_I64; + break; + case F32: + string = V8_S_F32; + break; + case F64: + string = V8_S_F64; + break; + case ANYREF: + string = V8_S_ANYREF; + break; + case FUNCREF: + string = V8_S_ANYFUNC; + break; default: // TODO(wasm+): support new value types assert(false); @@ -969,51 +1023,49 @@ auto valtype_to_v8( return store->v8_string(string); } -auto mutability_to_v8( - StoreImpl* store, Mutability mutability -) -> v8::Local { +auto mutability_to_v8(StoreImpl* store, Mutability mutability) + -> v8::Local { return v8::Boolean::New(store->isolate(), mutability == VAR); } void limits_to_v8(StoreImpl* store, Limits limits, v8::Local desc) { auto isolate = store->isolate(); auto context = store->context(); - ignore(desc->DefineOwnProperty(context, store->v8_string(V8_S_MINIMUM), - v8::Integer::NewFromUnsigned(isolate, limits.min))); + ignore(desc->DefineOwnProperty( + context, store->v8_string(V8_S_MINIMUM), + v8::Integer::NewFromUnsigned(isolate, limits.min))); if (limits.max != Limits(0).max) { - ignore(desc->DefineOwnProperty(context, store->v8_string(V8_S_MAXIMUM), - v8::Integer::NewFromUnsigned(isolate, limits.max))); + ignore(desc->DefineOwnProperty( + context, store->v8_string(V8_S_MAXIMUM), + v8::Integer::NewFromUnsigned(isolate, limits.max))); } } -auto globaltype_to_v8( - StoreImpl* store, const GlobalType* type -) -> v8::Local { +auto globaltype_to_v8(StoreImpl* store, const GlobalType* type) + -> v8::Local { auto isolate = store->isolate(); auto context = store->context(); auto desc = v8::Object::New(isolate); ignore(desc->DefineOwnProperty(context, store->v8_string(V8_S_VALUE), - valtype_to_v8(store, type->content()))); + valtype_to_v8(store, type->content()))); ignore(desc->DefineOwnProperty(context, store->v8_string(V8_S_MUTABLE), - mutability_to_v8(store, type->mutability()))); + mutability_to_v8(store, type->mutability()))); return desc; } -auto tabletype_to_v8( - StoreImpl* store, const TableType* type -) -> v8::Local { +auto tabletype_to_v8(StoreImpl* store, const TableType* type) + -> v8::Local { auto isolate = store->isolate(); auto context = store->context(); auto desc = v8::Object::New(isolate); ignore(desc->DefineOwnProperty(context, store->v8_string(V8_S_ELEMENT), - valtype_to_v8(store, type->element()))); + valtype_to_v8(store, type->element()))); limits_to_v8(store, type->limits(), desc); return desc; } -auto memorytype_to_v8( - StoreImpl* store, const MemoryType* type -) -> v8::Local { +auto memorytype_to_v8(StoreImpl* store, const MemoryType* type) + -> v8::Local { auto isolate = store->isolate(); auto desc = v8::Object::New(isolate); limits_to_v8(store, type->limits(), desc); @@ -1021,12 +1073,11 @@ auto memorytype_to_v8( } /* OBSOLETE? -wasm_externkind_t wasm_externkind_from_v8_kind(wasm_store_t* store, v8::Local kind) { - if (kind->SameValue(store->v8_string(V8_S_FUNCTION))) { - return WASM_EXTERN_FUNC; - } else if (kind->SameValue(store->v8_string(V8_S_GLOBAL))) { - return WASM_EXTERN_GLOBAL; - } else if (kind->SameValue(store->v8_string(V8_S_TABLE))) { +wasm_externkind_t wasm_externkind_from_v8_kind(wasm_store_t* store, +v8::Local kind) { if +(kind->SameValue(store->v8_string(V8_S_FUNCTION))) { return WASM_EXTERN_FUNC; } +else if (kind->SameValue(store->v8_string(V8_S_GLOBAL))) { return +WASM_EXTERN_GLOBAL; } else if (kind->SameValue(store->v8_string(V8_S_TABLE))) { return WASM_EXTERN_TABLE; } else if (kind->SameValue(store->v8_string(V8_S_MEMORY))) { return WASM_EXTERN_MEMORY; @@ -1035,22 +1086,23 @@ wasm_externkind_t wasm_externkind_from_v8_kind(wasm_store_t* store, v8::Local kind) { +own wasm_ExternType_t* wasm_externtype_new_from_v8_kind(wasm_store_t* store, +v8::Local kind) { // TODO: proper types switch (wasm_externkind_from_v8_kind(store, kind)) { case WASM_EXTERN_FUNC: return wasm_functype_as_externtype(wasm_functype_new_0_0()); case WASM_EXTERN_GLOBAL: - return wasm_globaltype_as_externtype(wasm_globaltype_new(wasm_valtype_new_anyref(), WASM_CONST)); - case WASM_EXTERN_TABLE: - return wasm_tabletype_as_externtype(wasm_tabletype_new(wasm_valtype_new_funcref(), wasm_limits(0, 0))); - case WASM_EXTERN_MEMORY: - return wasm_memtype_as_externtype(wasm_memtype_new(wasm_limits(0, 0))); + return +wasm_globaltype_as_externtype(wasm_globaltype_new(wasm_valtype_new_anyref(), +WASM_CONST)); case WASM_EXTERN_TABLE: return +wasm_tabletype_as_externtype(wasm_tabletype_new(wasm_valtype_new_funcref(), +wasm_limits(0, 0))); case WASM_EXTERN_MEMORY: return +wasm_memtype_as_externtype(wasm_memtype_new(wasm_limits(0, 0))); } } */ - // Strings /* OBSOLETE? @@ -1062,23 +1114,23 @@ own wasm_byte_vec_t wasm_v8_to_byte_vec(v8::Local string) { } */ - /////////////////////////////////////////////////////////////////////////////// // Runtime Values // References -template +template class RefImpl : public v8::Persistent { -public: + public: RefImpl() = delete; ~RefImpl() = delete; static auto make(StoreImpl* store, v8::Local obj) -> own { static_assert(sizeof(RefImpl) == sizeof(v8::Persistent), - "incompatible object layout"); + "incompatible object layout"); auto self = static_cast(store->make_handle()); - if (!self) return nullptr; + if (!self) + return nullptr; self->Reset(store->isolate(), obj); stats.make(Stats::categorize(*self), self); return make_own(seal(self)); @@ -1089,26 +1141,24 @@ class RefImpl : public v8::Persistent { return make(store(), v8_object()); } - auto store() const -> StoreImpl* { - return StoreImpl::get(isolate()); - } + auto store() const -> StoreImpl* { return StoreImpl::get(isolate()); } auto isolate() const -> v8::Isolate* { return wasm_v8::object_isolate(*this); } - auto v8_object() const -> v8::Local { - return Get(isolate()); - } + auto v8_object() const -> v8::Local { return Get(isolate()); } auto get_host_info() const -> void* { v8::HandleScope handle_scope(isolate()); auto store = this->store(); - v8::Local args[] = { v8_object() }; - auto maybe_result = store->v8_function(V8_F_WEAKMAP_GET)->Call( - store->context(), store->host_data_map(), 1, args); - if (maybe_result.IsEmpty()) return nullptr; + v8::Local args[] = {v8_object()}; + auto maybe_result = + store->v8_function(V8_F_WEAKMAP_GET) + ->Call(store->context(), store->host_data_map(), 1, args); + if (maybe_result.IsEmpty()) + return nullptr; return wasm_v8::managed_get(maybe_result.ToLocalChecked()); } @@ -1116,15 +1166,19 @@ class RefImpl : public v8::Persistent { v8::HandleScope handle_scope(isolate()); auto store = this->store(); auto managed = wasm_v8::managed_new(store->isolate(), info, finalizer); - v8::Local args[] = { v8_object(), managed }; - auto maybe_result = store->v8_function(V8_F_WEAKMAP_SET)->Call( - store->context(), store->host_data_map(), 2, args); - if (maybe_result.IsEmpty()) return; + v8::Local args[] = {v8_object(), managed}; + auto maybe_result = + store->v8_function(V8_F_WEAKMAP_SET) + ->Call(store->context(), store->host_data_map(), 2, args); + if (maybe_result.IsEmpty()) + return; } }; -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Ref::~Ref() { stats.free(Stats::categorize(*impl(this)), this); @@ -1132,7 +1186,7 @@ Ref::~Ref() { impl(this)->store()->free_handle(impl(this)); } -void Ref::operator delete(void *p) {} +void Ref::operator delete(void* p) {} auto Ref::copy() const -> own { return impl(this)->copy(); @@ -1151,7 +1205,6 @@ void Ref::set_host_info(void* info, void (*finalizer)(void*)) { impl(this)->set_host_info(info, finalizer); } - // Value Conversion auto ref_to_v8(StoreImpl* store, const Ref* r) -> v8::Local { @@ -1165,14 +1218,19 @@ auto ref_to_v8(StoreImpl* store, const Ref* r) -> v8::Local { auto val_to_v8(StoreImpl* store, const Val& v) -> v8::Local { auto isolate = store->isolate(); switch (v.kind()) { - case I32: return v8::Integer::NewFromUnsigned(isolate, v.i32()); - case I64: return v8::BigInt::New(isolate, v.i64()); - case F32: return v8::Number::New(isolate, v.f32()); - case F64: return v8::Number::New(isolate, v.f64()); + case I32: + return v8::Integer::NewFromUnsigned(isolate, v.i32()); + case I64: + return v8::BigInt::New(isolate, v.i64()); + case F32: + return v8::Number::New(isolate, v.f32()); + case F64: + return v8::Number::New(isolate, v.f64()); case ANYREF: case FUNCREF: return ref_to_v8(store, v.ref()); - default: assert(false); + default: + assert(false); } } @@ -1186,12 +1244,12 @@ auto v8_to_ref(StoreImpl* store, v8::Local value) -> own { } } -auto v8_to_val( - StoreImpl* store, v8::Local value, const ValType* t -) -> Val { +auto v8_to_val(StoreImpl* store, v8::Local value, const ValType* t) + -> Val { auto context = store->context(); switch (t->kind()) { - case I32: return Val(value->Int32Value(context).ToChecked()); + case I32: + return Val(value->Int32Value(context).ToChecked()); case I64: { auto bigint = value->ToBigInt(context).ToLocalChecked(); return Val(bigint->Int64Value()); @@ -1200,7 +1258,8 @@ auto v8_to_val( auto number = value->NumberValue(context).ToChecked(); return Val(static_cast(number)); } - case F64: return Val(value->NumberValue(context).ToChecked()); + case F64: + return Val(value->NumberValue(context).ToChecked()); case ANYREF: case FUNCREF: { return Val(v8_to_ref(store, value)); @@ -1208,22 +1267,20 @@ auto v8_to_val( } } - /////////////////////////////////////////////////////////////////////////////// // Runtime Objects // Frames struct FrameImpl { - FrameImpl( - own&& instance, uint32_t func_index, - size_t func_offset, size_t module_offset - ) : - instance(std::move(instance)), - func_index(func_index), - func_offset(func_offset), - module_offset(module_offset) - { + FrameImpl(own&& instance, + uint32_t func_index, + size_t func_offset, + size_t module_offset) + : instance(std::move(instance)), + func_index(func_index), + func_offset(func_offset), + module_offset(module_offset) { stats.make(Stats::FRAME, this); } @@ -1235,22 +1292,24 @@ struct FrameImpl { size_t module_offset; }; -template<> struct implement { using type = FrameImpl; }; - +template <> +struct implement { + using type = FrameImpl; +}; Frame::~Frame() { impl(this)->~FrameImpl(); } -void Frame::operator delete(void *p) { +void Frame::operator delete(void* p) { ::operator delete(p); } auto Frame::copy() const -> own { auto self = impl(this); - return own(seal(new(std::nothrow) FrameImpl( - self->instance->copy(), self->func_index, self->func_offset, - self->module_offset))); + return own(seal( + new (std::nothrow) FrameImpl(self->instance->copy(), self->func_index, + self->func_offset, self->module_offset))); } auto Frame::instance() const -> Instance* { @@ -1269,11 +1328,12 @@ auto Frame::module_offset() const -> size_t { return impl(this)->module_offset; } - // Traps -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Trap::~Trap() {} @@ -1286,9 +1346,10 @@ auto Trap::make(Store* store_abs, const Message& message) -> own { v8::Isolate* isolate = store->isolate(); v8::HandleScope handle_scope(isolate); - auto maybe_string = v8::String::NewFromUtf8(isolate, message.get(), - v8::NewStringType::kNormal, message.size()); - if (maybe_string.IsEmpty()) return own(); + auto maybe_string = v8::String::NewFromUtf8( + isolate, message.get(), v8::NewStringType::kNormal, message.size()); + if (maybe_string.IsEmpty()) + return own(); auto exception = v8::Exception::Error(maybe_string.ToLocalChecked()); return RefImpl::make(store, v8::Local::Cast(exception)); } @@ -1312,11 +1373,12 @@ auto Trap::trace() const -> ownvec { return ownvec::make(); } - // Foreign Objects -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Foreign::~Foreign() {} @@ -1333,11 +1395,12 @@ auto Foreign::make(Store* store_abs) -> own { return RefImpl::make(store, obj); } - // Modules -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Module::~Module() {} @@ -1351,12 +1414,13 @@ auto Module::validate(Store* store_abs, const vec& binary) -> bool { v8::HandleScope handle_scope(isolate); auto array_buffer = v8::ArrayBuffer::New( - isolate, const_cast(binary.get()), binary.size()); + isolate, const_cast(binary.get()), binary.size()); v8::Local args[] = {array_buffer}; - auto result = store->v8_function(V8_F_VALIDATE)->Call( - store->context(), v8::Undefined(isolate), 1, args); - if (result.IsEmpty()) return false; + auto result = store->v8_function(V8_F_VALIDATE) + ->Call(store->context(), v8::Undefined(isolate), 1, args); + if (result.IsEmpty()) + return false; return result.ToLocalChecked()->IsTrue(); } @@ -1368,98 +1432,97 @@ auto Module::make(Store* store_abs, const vec& binary) -> own { v8::HandleScope handle_scope(isolate); auto array_buffer = v8::ArrayBuffer::New( - isolate, const_cast(binary.get()), binary.size()); + isolate, const_cast(binary.get()), binary.size()); v8::Local args[] = {array_buffer}; auto maybe_obj = - store->v8_function(V8_F_MODULE)->NewInstance(context, 1, args); - if (maybe_obj.IsEmpty()) return nullptr; + store->v8_function(V8_F_MODULE)->NewInstance(context, 1, args); + if (maybe_obj.IsEmpty()) + return nullptr; return RefImpl::make(store, maybe_obj.ToLocalChecked()); } auto Module::imports() const -> ownvec { v8::HandleScope handle_scope(impl(this)->isolate()); auto module = impl(this)->v8_object(); - auto binary = vec::adopt( - wasm_v8::module_binary_size(module), - const_cast(wasm_v8::module_binary(module)) - ); + auto binary = + vec::adopt(wasm_v8::module_binary_size(module), + const_cast(wasm_v8::module_binary(module))); auto imports = wasm::bin::imports(binary); binary.release(); return imports; // return impl(this)->data->imports.copy(); -/* OBSOLETE? - auto store = module->store(); - auto isolate = store->isolate(); - auto context = store->context(); - v8::HandleScope handle_scope(isolate); + /* OBSOLETE? + auto store = module->store(); + auto isolate = store->isolate(); + auto context = store->context(); + v8::HandleScope handle_scope(isolate); - v8::Local args[] = { module->v8_object() }; - auto result = store->v8_function(V8_F_IMPORTS)->Call( - context, v8::Undefined(isolate), 1, args); - if (result.IsEmpty()) return wasm_importtype_vec_empty(); - auto array = v8::Local::Cast(result.ToLocalChecked()); - size_t size = array->Length(); - - wasm_importtype_vec_t imports = wasm_importtype_vec_new_uninitialized(size); - for (size_t i = 0; i < size; ++i) { - auto desc = v8::Local::Cast(array->Get(i)); - auto module_str = v8::Local::Cast( - desc->Get(context, store->v8_string(V8_S_MODULE)).ToLocalChecked()); - auto name_str = v8::Local::Cast( - desc->Get(context, store->v8_string(V8_S_NAME)).ToLocalChecked()); - auto kind_str = v8::Local::Cast( - desc->Get(context, store->v8_string(V8_S_KIND)).ToLocalChecked()); - - auto type = wasm_externtype_new_from_v8_kind(store, kind_str); - auto module = wasm_byte_vec_new_from_v8_string(module_str); - auto name = wasm_byte_vec_new_from_v8_string(name_str); - imports.data[i] = wasm_importtype_new(module, name, type); - } + v8::Local args[] = { module->v8_object() }; + auto result = store->v8_function(V8_F_IMPORTS)->Call( + context, v8::Undefined(isolate), 1, args); + if (result.IsEmpty()) return wasm_importtype_vec_empty(); + auto array = v8::Local::Cast(result.ToLocalChecked()); + size_t size = array->Length(); - return imports; -*/ + wasm_importtype_vec_t imports = wasm_importtype_vec_new_uninitialized(size); + for (size_t i = 0; i < size; ++i) { + auto desc = v8::Local::Cast(array->Get(i)); + auto module_str = v8::Local::Cast( + desc->Get(context, store->v8_string(V8_S_MODULE)).ToLocalChecked()); + auto name_str = v8::Local::Cast( + desc->Get(context, store->v8_string(V8_S_NAME)).ToLocalChecked()); + auto kind_str = v8::Local::Cast( + desc->Get(context, store->v8_string(V8_S_KIND)).ToLocalChecked()); + + auto type = wasm_externtype_new_from_v8_kind(store, kind_str); + auto module = wasm_byte_vec_new_from_v8_string(module_str); + auto name = wasm_byte_vec_new_from_v8_string(name_str); + imports.data[i] = wasm_importtype_new(module, name, type); + } + + return imports; + */ } auto Module::exports() const -> ownvec { v8::HandleScope handle_scope(impl(this)->isolate()); auto module = impl(this)->v8_object(); - auto binary = vec::adopt( - wasm_v8::module_binary_size(module), - const_cast(wasm_v8::module_binary(module)) - ); + auto binary = + vec::adopt(wasm_v8::module_binary_size(module), + const_cast(wasm_v8::module_binary(module))); auto exports = wasm::bin::exports(binary); binary.release(); return exports; // return impl(this)->data->exports.copy(); -/* OBSOLETE? - auto store = module->store(); - auto isolate = store->isolate(); - auto context = store->context(); - v8::HandleScope handle_scope(isolate); + /* OBSOLETE? + auto store = module->store(); + auto isolate = store->isolate(); + auto context = store->context(); + v8::HandleScope handle_scope(isolate); - v8::Local args[] = { module->v8_object() }; - auto result = store->v8_function(V8_F_EXPORTS)->Call( - context, v8::Undefined(isolate), 1, args); - if (result.IsEmpty()) return wasm_exporttype_vec_empty(); - auto array = v8::Local::Cast(result.ToLocalChecked()); - size_t size = array->Length(); - - wasm_exporttype_vec_t exports = wasm_exporttype_vec_new_uninitialized(size); - for (size_t i = 0; i < size; ++i) { - auto desc = v8::Local::Cast(array->Get(i)); - auto name_str = v8::Local::Cast( - desc->Get(context, store->v8_string(V8_S_NAME)).ToLocalChecked()); - auto kind_str = v8::Local::Cast( - desc->Get(context, store->v8_string(V8_S_KIND)).ToLocalChecked()); - - auto type = wasm_externtype_new_from_v8_kind(store, kind_str); - auto name = wasm_byte_vec_new_from_v8_string(name_str); - exports.data[i] = wasm_exporttype_new(name, type); - } + v8::Local args[] = { module->v8_object() }; + auto result = store->v8_function(V8_F_EXPORTS)->Call( + context, v8::Undefined(isolate), 1, args); + if (result.IsEmpty()) return wasm_exporttype_vec_empty(); + auto array = v8::Local::Cast(result.ToLocalChecked()); + size_t size = array->Length(); - return exports; -*/ + wasm_exporttype_vec_t exports = wasm_exporttype_vec_new_uninitialized(size); + for (size_t i = 0; i < size; ++i) { + auto desc = v8::Local::Cast(array->Get(i)); + auto name_str = v8::Local::Cast( + desc->Get(context, store->v8_string(V8_S_NAME)).ToLocalChecked()); + auto kind_str = v8::Local::Cast( + desc->Get(context, store->v8_string(V8_S_KIND)).ToLocalChecked()); + + auto type = wasm_externtype_new_from_v8_kind(store, kind_str); + auto name = wasm_byte_vec_new_from_v8_string(name_str); + exports.data[i] = wasm_exporttype_new(name, type); + } + + return exports; + */ } auto Module::serialize() const -> vec { @@ -1468,17 +1531,19 @@ auto Module::serialize() const -> vec { auto binary_size = wasm_v8::module_binary_size(module); auto serial_size = wasm_v8::module_serialize_size(module); auto size_size = wasm::bin::u64_size(binary_size); - auto buffer = vec::make_uninitialized( - size_size + binary_size + serial_size); + auto buffer = + vec::make_uninitialized(size_size + binary_size + serial_size); auto ptr = buffer.get(); wasm::bin::encode_u64(ptr, binary_size); std::memcpy(ptr, wasm_v8::module_binary(module), binary_size); ptr += binary_size; - if (!wasm_v8::module_serialize(module, ptr, serial_size)) buffer.reset(); + if (!wasm_v8::module_serialize(module, ptr, serial_size)) + buffer.reset(); return buffer; } -auto Module::deserialize(Store* store_abs, const vec& serialized) -> own { +auto Module::deserialize(Store* store_abs, const vec& serialized) + -> own { auto store = impl(store_abs); auto isolate = store->isolate(); v8::HandleScope handle_scope(isolate); @@ -1486,23 +1551,26 @@ auto Module::deserialize(Store* store_abs, const vec& serialized) -> own auto binary_size = wasm::bin::u64(ptr); auto size_size = ptr - serialized.get(); auto serial_size = serialized.size() - size_size - binary_size; - auto maybe_obj = wasm_v8::module_deserialize( - isolate, ptr, binary_size, ptr + binary_size, serial_size); - if (maybe_obj.IsEmpty()) return nullptr; + auto maybe_obj = wasm_v8::module_deserialize(isolate, ptr, binary_size, + ptr + binary_size, serial_size); + if (maybe_obj.IsEmpty()) + return nullptr; return RefImpl::make(store, maybe_obj.ToLocalChecked()); } - // TODO(v8): do better when V8 can do better. -template<> struct implement> { using type = vec; }; +template <> +struct implement> { + using type = vec; +}; -template<> +template <> Shared::~Shared() { stats.free(Stats::MODULE, this, Stats::SHARED); impl(this)->~vec(); } -template<> +template <> void Shared::operator delete(void* p) { ::operator delete(p); } @@ -1517,13 +1585,12 @@ auto Module::obtain(Store* store, const Shared* shared) -> own { return Module::deserialize(store, *impl(shared)); } - - - // Externals -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Extern::~Extern() {} @@ -1538,10 +1605,14 @@ auto Extern::kind() const -> ExternKind { auto Extern::type() const -> own { switch (kind()) { - case EXTERN_FUNC: return func()->type(); - case EXTERN_GLOBAL: return global()->type(); - case EXTERN_TABLE: return table()->type(); - case EXTERN_MEMORY: return memory()->type(); + case EXTERN_FUNC: + return func()->type(); + case EXTERN_GLOBAL: + return global()->type(); + case EXTERN_TABLE: + return table()->type(); + case EXTERN_MEMORY: + return memory()->type(); } } @@ -1581,11 +1652,12 @@ auto extern_to_v8(const Extern* ex) -> v8::Local { return impl(ex)->v8_object(); } - // Function Instances -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Func::~Func() {} @@ -1604,23 +1676,31 @@ struct FuncData { void (*finalizer)(void*); void* env; - FuncData(Store* store, const FuncType* type, Kind kind) : - store(store), type(type->copy()), kind(kind), finalizer(nullptr) - { + FuncData(Store* store, const FuncType* type, Kind kind) + : store(store), type(type->copy()), kind(kind), finalizer(nullptr) { stats.make(Stats::FUNCDATA_FUNCTYPE, nullptr); - stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, type->params().size()); - stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, type->results().size()); - if (type->params().get()) stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); - if (type->results().get()) stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); + stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, + type->params().size()); + stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, + type->results().size()); + if (type->params().get()) + stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); + if (type->results().get()) + stats.make(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); } ~FuncData() { stats.free(Stats::FUNCDATA_FUNCTYPE, nullptr); - stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, type->params().size()); - stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, type->results().size()); - if (type->params().get()) stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); - if (type->results().get()) stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); - if (finalizer) (*finalizer)(env); + stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, + type->params().size()); + stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::OWN, + type->results().size()); + if (type->params().get()) + stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); + if (type->results().get()) + stats.free(Stats::FUNCDATA_VALTYPE, nullptr, Stats::VEC); + if (finalizer) + (*finalizer)(env); } static void v8_callback(const v8::FunctionCallbackInfo&); @@ -1637,10 +1717,11 @@ auto make_func(Store* store_abs, FuncData* data) -> own { // Create V8 function auto v8_data = wasm_v8::foreign_new(isolate, data); - auto function_template = v8::FunctionTemplate::New( - isolate, &FuncData::v8_callback, v8_data); + auto function_template = + v8::FunctionTemplate::New(isolate, &FuncData::v8_callback, v8_data); auto maybe_func_obj = function_template->GetFunction(context); - if (maybe_func_obj.IsEmpty()) return own(); + if (maybe_func_obj.IsEmpty()) + return own(); auto func_obj = maybe_func_obj.ToLocalChecked(); // Create wrapper instance @@ -1653,18 +1734,18 @@ auto make_func(Store* store_abs, FuncData* data) -> own { ignore(imports_obj->DefineOwnProperty(context, str, module_obj)); ignore(module_obj->DefineOwnProperty(context, str, func_obj)); - v8::Local instantiate_args[] = { - impl(module.get())->v8_object(), imports_obj - }; - auto instance_obj = store->v8_function(V8_F_INSTANCE)->NewInstance( - context, 2, instantiate_args).ToLocalChecked(); + v8::Local instantiate_args[] = {impl(module.get())->v8_object(), + imports_obj}; + auto instance_obj = store->v8_function(V8_F_INSTANCE) + ->NewInstance(context, 2, instantiate_args) + .ToLocalChecked(); assert(!instance_obj.IsEmpty()); assert(instance_obj->IsObject()); auto exports_obj = wasm_v8::instance_exports(instance_obj); assert(!exports_obj.IsEmpty()); assert(exports_obj->IsObject()); auto wrapped_func_obj = v8::Local::Cast( - exports_obj->Get(context, str).ToLocalChecked()); + exports_obj->Get(context, str).ToLocalChecked()); assert(!wrapped_func_obj.IsEmpty()); assert(wrapped_func_obj->IsFunction()); @@ -1694,18 +1775,18 @@ auto func_type(v8::Local v8_func) -> own { } // namespace -auto Func::make( - Store* store, const FuncType* type, Func::callback callback -) -> own { +auto Func::make(Store* store, const FuncType* type, Func::callback callback) + -> own { auto data = new FuncData(store, type, FuncData::CALLBACK); data->callback = callback; return make_func(store, data); } -auto Func::make( - Store* store, const FuncType* type, - callback_with_env callback, void* env, void (*finalizer)(void*) -) -> own { +auto Func::make(Store* store, + const FuncType* type, + callback_with_env callback, + void* env, + void (*finalizer)(void*)) -> own { auto data = new FuncData(store, type, FuncData::CALLBACK_WITH_ENV); data->callback_with_env = callback; data->env = env; @@ -1742,7 +1823,7 @@ auto Func::call(const Val args[], Val results[]) const -> own { // TODO: cache v8_args array per thread. auto v8_args = std::unique_ptr[]>( - new(std::nothrow) v8::Local[param_types.size()]); + new (std::nothrow) v8::Local[param_types.size()]); for (size_t i = 0; i < param_types.size(); ++i) { assert(args[i].kind() == param_types[i]->kind()); v8_args[i] = val_to_v8(store, args[i]); @@ -1750,15 +1831,15 @@ auto Func::call(const Val args[], Val results[]) const -> own { v8::TryCatch handler(isolate); auto v8_function = v8::Local::Cast(func->v8_object()); - auto maybe_val = v8_function->Call( - context, v8::Undefined(isolate), param_types.size(), v8_args.get()); + auto maybe_val = v8_function->Call(context, v8::Undefined(isolate), + param_types.size(), v8_args.get()); if (handler.HasCaught()) { auto exception = handler.Exception(); if (!exception->IsObject()) { auto maybe_string = exception->ToString(store->context()); - auto string = maybe_string.IsEmpty() - ? store->v8_string(V8_S_EMPTY) : maybe_string.ToLocalChecked(); + auto string = maybe_string.IsEmpty() ? store->v8_string(V8_S_EMPTY) + : maybe_string.ToLocalChecked(); exception = v8::Exception::Error(string); } return RefImpl::make(store, v8::Local::Cast(exception)); @@ -1776,8 +1857,8 @@ auto Func::call(const Val args[], Val results[]) const -> own { for (size_t i = 0; i < result_types.size(); ++i) { auto maybe = array->Get(context, i); assert(!maybe.IsEmpty()); - new (&results[i]) Val(v8_to_val( - store, maybe.ToLocalChecked(), result_types[i].get())); + new (&results[i]) + Val(v8_to_val(store, maybe.ToLocalChecked(), result_types[i].get())); } } return nullptr; @@ -1835,11 +1916,12 @@ void FuncData::finalize_func_data(void* data) { delete reinterpret_cast(data); } - // Global Instances -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Global::~Global() {} @@ -1847,9 +1929,8 @@ auto Global::copy() const -> own { return impl(this)->copy(); } -auto Global::make( - Store* store_abs, const GlobalType* type, const Val& val -) -> own { +auto Global::make(Store* store_abs, const GlobalType* type, const Val& val) + -> own { auto store = impl(store_abs); auto isolate = store->isolate(); v8::HandleScope handle_scope(isolate); @@ -1861,12 +1942,13 @@ auto Global::make( auto binary = wasm::bin::wrapper(type); auto module = Module::make(store_abs, binary); - v8::Local instantiate_args[] = { impl(module.get())->v8_object() }; - auto instance_obj = store->v8_function(V8_F_INSTANCE)->NewInstance( - context, 1, instantiate_args).ToLocalChecked(); + v8::Local instantiate_args[] = {impl(module.get())->v8_object()}; + auto instance_obj = store->v8_function(V8_F_INSTANCE) + ->NewInstance(context, 1, instantiate_args) + .ToLocalChecked(); auto exports_obj = wasm_v8::instance_exports(instance_obj); auto obj = v8::Local::Cast( - exports_obj->Get(context, store->v8_string(V8_S_EMPTY)).ToLocalChecked()); + exports_obj->Get(context, store->v8_string(V8_S_EMPTY)).ToLocalChecked()); assert(!obj.IsEmpty() && obj->IsObject()); auto global = RefImpl::make(store, obj); @@ -1888,10 +1970,14 @@ auto Global::get() const -> Val { v8::HandleScope handle_scope(impl(this)->isolate()); auto v8_global = impl(this)->v8_object(); switch (type()->content()->kind()) { - case I32: return Val(wasm_v8::global_get_i32(v8_global)); - case I64: return Val(wasm_v8::global_get_i64(v8_global)); - case F32: return Val(wasm_v8::global_get_f32(v8_global)); - case F64: return Val(wasm_v8::global_get_f64(v8_global)); + case I32: + return Val(wasm_v8::global_get_i32(v8_global)); + case I64: + return Val(wasm_v8::global_get_i64(v8_global)); + case F32: + return Val(wasm_v8::global_get_f32(v8_global)); + case F64: + return Val(wasm_v8::global_get_f64(v8_global)); case ANYREF: case FUNCREF: { auto store = impl(this)->store(); @@ -1906,10 +1992,14 @@ void Global::set(const Val& val) { v8::HandleScope handle_scope(impl(this)->isolate()); auto v8_global = impl(this)->v8_object(); switch (val.kind()) { - case I32: return wasm_v8::global_set_i32(v8_global, val.i32()); - case I64: return wasm_v8::global_set_i64(v8_global, val.i64()); - case F32: return wasm_v8::global_set_f32(v8_global, val.f32()); - case F64: return wasm_v8::global_set_f64(v8_global, val.f64()); + case I32: + return wasm_v8::global_set_i32(v8_global, val.i32()); + case I64: + return wasm_v8::global_set_i64(v8_global, val.i64()); + case F32: + return wasm_v8::global_set_f32(v8_global, val.f32()); + case F64: + return wasm_v8::global_set_f64(v8_global, val.f64()); case ANYREF: case FUNCREF: { auto store = impl(this)->store(); @@ -1920,11 +2010,12 @@ void Global::set(const Val& val) { } } - // Table Instances -template<> struct implement
{ using type = RefImpl
; }; - +template <> +struct implement
{ + using type = RefImpl
; +}; Table::~Table() {} @@ -1932,20 +2023,21 @@ auto Table::copy() const -> own
{ return impl(this)->copy(); } -auto Table::make( - Store* store_abs, const TableType* type, const Ref* ref -) -> own
{ +auto Table::make(Store* store_abs, const TableType* type, const Ref* ref) + -> own
{ auto store = impl(store_abs); auto isolate = store->isolate(); v8::HandleScope handle_scope(isolate); auto context = store->context(); v8::Local init = v8::Null(isolate); - if (ref) init = impl(ref)->v8_object(); + if (ref) + init = impl(ref)->v8_object(); v8::Local args[] = {tabletype_to_v8(store, type), init}; auto maybe_obj = - store->v8_function(V8_F_TABLE)->NewInstance(context, 2, args); - if (maybe_obj.IsEmpty()) return own
(); + store->v8_function(V8_F_TABLE)->NewInstance(context, 2, args); + if (maybe_obj.IsEmpty()) + return own
(); auto table = RefImpl
::make(store, maybe_obj.ToLocalChecked()); // TODO(wasm+): pass reference initialiser as parameter if (table && ref) { @@ -1971,7 +2063,8 @@ auto Table::type() const -> own { auto Table::get(size_t index) const -> own { v8::HandleScope handle_scope(impl(this)->isolate()); auto maybe = wasm_v8::table_get(impl(this)->v8_object(), index); - if (maybe.IsEmpty()) return own(); + if (maybe.IsEmpty()) + return own(); auto obj = v8::Local::Cast(maybe.ToLocalChecked()); return v8_to_ref(impl(this)->store(), obj); } @@ -1993,11 +2086,12 @@ auto Table::grow(size_t delta, const Ref* ref) -> bool { return wasm_v8::table_grow(impl(this)->v8_object(), delta, val); } - // Memory Instances -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Memory::~Memory() {} @@ -2011,10 +2105,11 @@ auto Memory::make(Store* store_abs, const MemoryType* type) -> own { v8::HandleScope handle_scope(isolate); auto context = store->context(); - v8::Local args[] = { memorytype_to_v8(store, type) }; + v8::Local args[] = {memorytype_to_v8(store, type)}; auto maybe_obj = - store->v8_function(V8_F_MEMORY)->NewInstance(context, 1, args); - if (maybe_obj.IsEmpty()) return own(); + store->v8_function(V8_F_MEMORY)->NewInstance(context, 1, args); + if (maybe_obj.IsEmpty()) + return own(); return RefImpl::make(store, maybe_obj.ToLocalChecked()); } @@ -2047,11 +2142,12 @@ auto Memory::grow(pages_t delta) -> bool { return wasm_v8::memory_grow(impl(this)->v8_object(), delta); } - // Module Instances -template<> struct implement { using type = RefImpl; }; - +template <> +struct implement { + using type = RefImpl; +}; Instance::~Instance() {} @@ -2059,10 +2155,10 @@ auto Instance::copy() const -> own { return impl(this)->copy(); } -auto Instance::make( - Store* store_abs, const Module* module_abs, const Extern* const imports[], - own* trap -) -> own { +auto Instance::make(Store* store_abs, + const Module* module_abs, + const Extern* const imports[], + own* trap) -> own { auto store = impl(store_abs); auto module = impl(module_abs); auto isolate = store->isolate(); @@ -2071,48 +2167,50 @@ auto Instance::make( assert(wasm_v8::object_isolate(module->v8_object()) == isolate); - if (trap) *trap = nullptr; + if (trap) + *trap = nullptr; auto import_types = module_abs->imports(); auto imports_obj = v8::Object::New(isolate); for (size_t i = 0; i < import_types.size(); ++i) { auto type = import_types[i].get(); auto maybe_module = v8::String::NewFromOneByte( - isolate, reinterpret_cast(type->module().get()), - v8::NewStringType::kNormal, type->module().size() - ); - if (maybe_module.IsEmpty()) return own(); + isolate, reinterpret_cast(type->module().get()), + v8::NewStringType::kNormal, type->module().size()); + if (maybe_module.IsEmpty()) + return own(); auto module_str = maybe_module.ToLocalChecked(); auto maybe_name = v8::String::NewFromOneByte( - isolate, reinterpret_cast(type->name().get()), - v8::NewStringType::kNormal, type->name().size() - ); - if (maybe_name.IsEmpty()) return own(); + isolate, reinterpret_cast(type->name().get()), + v8::NewStringType::kNormal, type->name().size()); + if (maybe_name.IsEmpty()) + return own(); auto name_str = maybe_name.ToLocalChecked(); v8::Local module_obj; if (imports_obj->HasOwnProperty(context, module_str).ToChecked()) { module_obj = v8::Local::Cast( - imports_obj->Get(context, module_str).ToLocalChecked()); + imports_obj->Get(context, module_str).ToLocalChecked()); } else { module_obj = v8::Object::New(isolate); ignore(imports_obj->DefineOwnProperty(context, module_str, module_obj)); } - ignore(module_obj->DefineOwnProperty( - context, name_str, extern_to_v8(imports[i]))); + ignore(module_obj->DefineOwnProperty(context, name_str, + extern_to_v8(imports[i]))); } v8::TryCatch handler(isolate); v8::Local instantiate_args[] = {module->v8_object(), imports_obj}; - auto obj = store->v8_function(V8_F_INSTANCE)->NewInstance( - context, 2, instantiate_args).ToLocalChecked(); + auto obj = store->v8_function(V8_F_INSTANCE) + ->NewInstance(context, 2, instantiate_args) + .ToLocalChecked(); if (handler.HasCaught() && trap) { auto exception = handler.Exception(); if (!exception->IsObject()) { auto maybe_string = exception->ToString(store->context()); - auto string = maybe_string.IsEmpty() - ? store->v8_string(V8_S_EMPTY) : maybe_string.ToLocalChecked(); + auto string = maybe_string.IsEmpty() ? store->v8_string(V8_S_EMPTY) + : maybe_string.ToLocalChecked(); exception = v8::Exception::Error(string); } *trap = RefImpl::make(store, v8::Local::Cast(exception)); @@ -2137,16 +2235,18 @@ auto Instance::exports() const -> ownvec { auto module = RefImpl::make(store, module_obj); auto export_types = module->exports(); auto exports = ownvec::make_uninitialized(export_types.size()); - if (!exports) return ownvec::invalid(); + if (!exports) + return ownvec::invalid(); for (size_t i = 0; i < export_types.size(); ++i) { auto& name = export_types[i]->name(); - auto maybe_name_obj = v8::String::NewFromUtf8(isolate, name.get(), - v8::NewStringType::kNormal, name.size()); - if (maybe_name_obj.IsEmpty()) return ownvec::invalid(); + auto maybe_name_obj = v8::String::NewFromUtf8( + isolate, name.get(), v8::NewStringType::kNormal, name.size()); + if (maybe_name_obj.IsEmpty()) + return ownvec::invalid(); auto name_obj = maybe_name_obj.ToLocalChecked(); auto obj = v8::Local::Cast( - exports_obj->Get(context, name_obj).ToLocalChecked()); + exports_obj->Get(context, name_obj).ToLocalChecked()); auto type = export_types[i]->type(); switch (type->kind()) {