diff options
Diffstat (limited to 'deps/v8/third_party/wasm-api/example')
32 files changed, 1276 insertions, 108 deletions
diff --git a/deps/v8/third_party/wasm-api/example/callback.c b/deps/v8/third_party/wasm-api/example/callback.c index f3b9018594..e17429bdd2 100644 --- a/deps/v8/third_party/wasm-api/example/callback.c +++ b/deps/v8/third_party/wasm-api/example/callback.c @@ -111,7 +111,8 @@ int main(int argc, const char* argv[]) { 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); + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/deps/v8/third_party/wasm-api/example/callback.cc b/deps/v8/third_party/wasm-api/example/callback.cc index a9ee9aa919..d9f8751ea6 100644 --- a/deps/v8/third_party/wasm-api/example/callback.cc +++ b/deps/v8/third_party/wasm-api/example/callback.cc @@ -36,7 +36,7 @@ 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<wasm::Trap*> { +) -> wasm::own<wasm::Trap> { std::cout << "Calling back..." << std::endl << "> " << args[0] << std::endl; results[0] = args[0].copy(); return nullptr; @@ -46,7 +46,7 @@ auto print_callback( // A function closure. auto closure_callback( void* env, const wasm::Val args[], wasm::Val results[] -) -> wasm::own<wasm::Trap*> { +) -> wasm::own<wasm::Trap> { auto i = *reinterpret_cast<int*>(env); std::cout << "Calling back closure..." << std::endl; std::cout << "> " << i << std::endl; @@ -73,7 +73,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -81,14 +81,14 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Create external print functions. std::cout << "Creating callback..." << std::endl; auto print_type = wasm::FuncType::make( - wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)), - wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)) + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::I32)), + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::I32)) ); auto print_func = wasm::Func::make(store, print_type.get(), print_callback); @@ -96,8 +96,8 @@ void run() { std::cout << "Creating closure..." << std::endl; int i = 42; auto closure_type = wasm::FuncType::make( - wasm::vec<wasm::ValType*>::make(), - wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)) + wasm::ownvec<wasm::ValType>::make(), + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::I32)) ); auto closure_func = wasm::Func::make(store, closure_type.get(), closure_callback, &i); @@ -107,7 +107,7 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -115,7 +115,7 @@ void run() { auto exports = instance->exports(); if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { std::cout << "> Error accessing export!" << std::endl; - return; + exit(1); } auto run_func = exports[0]->func(); @@ -125,7 +125,7 @@ void run() { wasm::Val results[1]; if (run_func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; - return; + exit(1); } // Print result. diff --git a/deps/v8/third_party/wasm-api/example/finalize.c b/deps/v8/third_party/wasm-api/example/finalize.c index 6841617262..247368f28e 100644 --- a/deps/v8/third_party/wasm-api/example/finalize.c +++ b/deps/v8/third_party/wasm-api/example/finalize.c @@ -9,23 +9,21 @@ const int iterations = 100000; +int live_count = 0; + void finalize(void* data) { int i = (int)data; if (i % (iterations / 10) == 0) printf("Finalizing #%d...\n", i); + --live_count; } -int main(int argc, const char* argv[]) { - // Initialize. - printf("Initializing...\n"); - wasm_engine_t* engine = wasm_engine_new(); - wasm_store_t* store = wasm_store_new(engine); - +void run_in_store(wasm_store_t* store) { // Load binary. printf("Loading binary...\n"); FILE* file = fopen("finalize.wasm", "r"); if (!file) { printf("> Error loading module!\n"); - return 1; + exit(1); } fseek(file, 0L, SEEK_END); size_t file_size = ftell(file); @@ -34,7 +32,7 @@ int main(int argc, const char* argv[]) { wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { printf("> Error loading module!\n"); - return 1; + exit(1); } fclose(file); @@ -43,7 +41,7 @@ int main(int argc, const char* argv[]) { own wasm_module_t* module = wasm_module_new(store, &binary); if (!module) { printf("> Error compiling module!\n"); - return 1; + exit(1); } wasm_byte_vec_delete(&binary); @@ -52,21 +50,57 @@ int main(int argc, const char* argv[]) { printf("Instantiating modules...\n"); for (int i = 0; i <= iterations; ++i) { if (i % (iterations / 10) == 0) printf("%d\n", i); - own wasm_instance_t* instance = wasm_instance_new(store, module, NULL); + own wasm_instance_t* instance = + wasm_instance_new(store, module, NULL, NULL); if (!instance) { printf("> Error instantiating module %d!\n", i); - return 1; + exit(1); } void* data = (void*)(intptr_t)i; wasm_instance_set_host_info_with_finalizer(instance, data, &finalize); wasm_instance_delete(instance); + ++live_count; } wasm_module_delete(module); +} + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + + printf("Live count %d\n", live_count); + printf("Creating store 1...\n"); + wasm_store_t* store1 = wasm_store_new(engine); + + printf("Running in store 1...\n"); + run_in_store(store1); + printf("Live count %d\n", live_count); + + printf("Creating store 2...\n"); + wasm_store_t* store2 = wasm_store_new(engine); + + printf("Running in store 2...\n"); + run_in_store(store2); + printf("Live count %d\n", live_count); + + printf("Deleting store 2...\n"); + wasm_store_delete(store2); + printf("Live count %d\n", live_count); + + printf("Running in store 1...\n"); + run_in_store(store1); + printf("Live count %d\n", live_count); + + printf("Deleting store 1...\n"); + wasm_store_delete(store1); + printf("Live count %d\n", live_count); + + assert(live_count == 0); // Shut down. printf("Shutting down...\n"); - wasm_store_delete(store); wasm_engine_delete(engine); // All done. diff --git a/deps/v8/third_party/wasm-api/example/finalize.cc b/deps/v8/third_party/wasm-api/example/finalize.cc index a354a2601d..64e134b8d8 100644 --- a/deps/v8/third_party/wasm-api/example/finalize.cc +++ b/deps/v8/third_party/wasm-api/example/finalize.cc @@ -9,20 +9,17 @@ const int iterations = 100000; +int live_count = 0; + void finalize(void* data) { intptr_t i = reinterpret_cast<intptr_t>(data); if (i % (iterations / 10) == 0) { std::cout << "Finalizing #" << i << "..." << std::endl; } + --live_count; } -void run() { - // Initialize. - std::cout << "Initializing..." << std::endl; - auto engine = wasm::Engine::make(); - auto store_ = wasm::Store::make(engine.get()); - auto store = store_.get(); - +void run_in_store(wasm::Store* store) { // Load binary. std::cout << "Loading binary..." << std::endl; std::ifstream file("finalize.wasm"); @@ -34,7 +31,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -42,7 +39,7 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Instantiate. @@ -52,9 +49,10 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), nullptr); if (!instance) { std::cout << "> Error instantiating module " << i << "!" << std::endl; - return; + exit(1); } instance->set_host_info(reinterpret_cast<void*>(i), &finalize); + ++live_count; } // Shut down. @@ -62,8 +60,43 @@ void run() { } +void run() { + // Initialize. + std::cout << "Initializing..." << std::endl; + auto engine = wasm::Engine::make(); + + std::cout << "Live count " << live_count << std::endl; + std::cout << "Creating store 1..." << std::endl; + auto store1 = wasm::Store::make(engine.get()); + + std::cout << "Running in store 1..." << std::endl; + run_in_store(store1.get()); + std::cout << "Live count " << live_count << std::endl; + + { + std::cout << "Creating store 2..." << std::endl; + auto store2 = wasm::Store::make(engine.get()); + + std::cout << "Running in store 2..." << std::endl; + run_in_store(store2.get()); + std::cout << "Live count " << live_count << std::endl; + + std::cout << "Deleting store 2..." << std::endl; + std::cout << "Live count " << live_count << std::endl; + } + + std::cout << "Running in store 1..." << std::endl; + run_in_store(store1.get()); + std::cout << "Live count " << live_count << std::endl; + + std::cout << "Deleting store 1..." << std::endl; +} + + int main(int argc, const char* argv[]) { run(); + std::cout << "Live count " << live_count << std::endl; + assert(live_count == 0); std::cout << "Done." << std::endl; return 0; } diff --git a/deps/v8/third_party/wasm-api/example/global.c b/deps/v8/third_party/wasm-api/example/global.c index b82d86242e..5fe357cd4c 100644 --- a/deps/v8/third_party/wasm-api/example/global.c +++ b/deps/v8/third_party/wasm-api/example/global.c @@ -91,13 +91,17 @@ int main(int argc, const char* argv[]) { 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); + own wasm_global_t* const_f32_import = + 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); + own wasm_global_t* const_i64_import = + 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); + own wasm_global_t* var_f32_import = + 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); + own wasm_global_t* var_i64_import = + wasm_global_new(store, var_i64_type, &val_i64_4); wasm_globaltype_delete(const_f32_type); wasm_globaltype_delete(const_i64_type); @@ -112,7 +116,8 @@ int main(int argc, const char* argv[]) { 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); + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -142,6 +147,11 @@ int main(int argc, const char* argv[]) { wasm_func_t* set_var_f32_export = get_export_func(&exports, i++); wasm_func_t* set_var_i64_export = get_export_func(&exports, i++); + // Try cloning. + own wasm_global_t* copy = wasm_global_copy(var_f32_import); + assert(wasm_global_same(var_f32_import, copy)); + wasm_global_delete(copy); + // Interact. printf("Accessing globals...\n"); diff --git a/deps/v8/third_party/wasm-api/example/global.cc b/deps/v8/third_party/wasm-api/example/global.cc index 75a2513c82..811024e65d 100644 --- a/deps/v8/third_party/wasm-api/example/global.cc +++ b/deps/v8/third_party/wasm-api/example/global.cc @@ -7,7 +7,7 @@ #include "wasm.hh" -auto get_export_global(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Global* { +auto get_export_global(wasm::ownvec<wasm::Extern>& 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,7 @@ auto get_export_global(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Glo return exports[i]->global(); } -auto get_export_func(const wasm::vec<wasm::Extern*>& exports, size_t i) -> const wasm::Func* { +auto get_export_func(const wasm::ownvec<wasm::Extern>& 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); @@ -67,7 +67,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -75,7 +75,7 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Create external globals. @@ -102,7 +102,7 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -126,6 +126,9 @@ void run() { auto set_var_f32_export = get_export_func(exports, i++); auto set_var_i64_export = get_export_func(exports, i++); + // Try cloning. + assert(var_f32_import->copy()->same(var_f32_import.get())); + // Interact. std::cout << "Accessing globals..." << std::endl; diff --git a/deps/v8/third_party/wasm-api/example/hello.c b/deps/v8/third_party/wasm-api/example/hello.c index b1c8c5fee5..e4ef9837ff 100644 --- a/deps/v8/third_party/wasm-api/example/hello.c +++ b/deps/v8/third_party/wasm-api/example/hello.c @@ -62,7 +62,8 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) }; - own wasm_instance_t* instance = wasm_instance_new(store, module, imports); + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/deps/v8/third_party/wasm-api/example/hello.cc b/deps/v8/third_party/wasm-api/example/hello.cc index 4956be885f..e009b3b50d 100644 --- a/deps/v8/third_party/wasm-api/example/hello.cc +++ b/deps/v8/third_party/wasm-api/example/hello.cc @@ -10,7 +10,7 @@ // A function to be called from Wasm code. auto hello_callback( const wasm::Val args[], wasm::Val results[] -) -> wasm::own<wasm::Trap*> { +) -> wasm::own<wasm::Trap> { std::cout << "Calling back..." << std::endl; std::cout << "> Hello world!" << std::endl; return nullptr; @@ -35,7 +35,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -43,13 +43,13 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Create external print functions. std::cout << "Creating callback..." << std::endl; auto hello_type = wasm::FuncType::make( - wasm::vec<wasm::ValType*>::make(), wasm::vec<wasm::ValType*>::make() + wasm::ownvec<wasm::ValType>::make(), wasm::ownvec<wasm::ValType>::make() ); auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback); @@ -59,7 +59,7 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -67,7 +67,7 @@ void run() { auto exports = instance->exports(); if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { std::cout << "> Error accessing export!" << std::endl; - return; + exit(1); } auto run_func = exports[0]->func(); @@ -75,7 +75,7 @@ void run() { std::cout << "Calling export..." << std::endl; if (run_func->call()) { std::cout << "> Error calling function!" << std::endl; - return; + exit(1); } // Shut down. diff --git a/deps/v8/third_party/wasm-api/example/hostref.c b/deps/v8/third_party/wasm-api/example/hostref.c new file mode 100644 index 0000000000..b70218e610 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/hostref.c @@ -0,0 +1,269 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> + +#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[] +) { + printf("Calling back...\n> "); + printf("> %p\n", + 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); + exit(1); + } + return wasm_extern_as_func(exports->data[i]); +} + +wasm_global_t* get_export_global(const wasm_extern_vec_t* exports, size_t i) { + if (exports->size <= i || !wasm_extern_as_global(exports->data[i])) { + printf("> Error accessing global export %zu!\n", i); + exit(1); + } + return wasm_extern_as_global(exports->data[i]); +} + +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); + exit(1); + } + 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); + wasm_val_t results[1]; + if (wasm_func_call(func, NULL, results)) { + printf("> Error calling function!\n"); + exit(1); + } + printf("okay\n"); + return results[0].of.ref; +} + +void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) { + printf("call_r_v... "); fflush(stdout); + wasm_val_t args[1]; + args[0].kind = WASM_ANYREF; + args[0].of.ref = ref; + if (wasm_func_call(func, args, NULL)) { + printf("> Error calling function!\n"); + exit(1); + } + printf("okay\n"); +} + +own wasm_ref_t* call_r_r(const wasm_func_t* func, wasm_ref_t* ref) { + printf("call_r_r... "); fflush(stdout); + wasm_val_t args[1]; + args[0].kind = WASM_ANYREF; + args[0].of.ref = ref; + wasm_val_t results[1]; + if (wasm_func_call(func, args, results)) { + printf("> Error calling function!\n"); + exit(1); + } + printf("okay\n"); + return results[0].of.ref; +} + +void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) { + printf("call_ir_v... "); fflush(stdout); + wasm_val_t args[2]; + args[0].kind = WASM_I32; + args[0].of.i32 = i; + args[1].kind = WASM_ANYREF; + args[1].of.ref = ref; + if (wasm_func_call(func, args, NULL)) { + printf("> Error calling function!\n"); + exit(1); + } + printf("okay\n"); +} + +own wasm_ref_t* call_i_r(const wasm_func_t* func, int32_t i) { + printf("call_i_r... "); fflush(stdout); + wasm_val_t args[1]; + args[0].kind = WASM_I32; + args[0].of.i32 = i; + wasm_val_t results[1]; + if (wasm_func_call(func, args, results)) { + printf("> Error calling function!\n"); + exit(1); + } + printf("okay\n"); + return results[0].of.ref; +} + +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); + exit(1); + } + if (actual) wasm_ref_delete(actual); +} + + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + // Load binary. + printf("Loading binary...\n"); + FILE* file = fopen("hostref.wasm", "r"); + if (!file) { + printf("> Error loading module!\n"); + return 1; + } + fseek(file, 0L, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0L, SEEK_SET); + wasm_byte_vec_t binary; + wasm_byte_vec_new_uninitialized(&binary, file_size); + if (fread(binary.data, file_size, 1, file) != 1) { + printf("> Error loading module!\n"); + return 1; + } + fclose(file); + + // Compile. + printf("Compiling module...\n"); + own wasm_module_t* module = wasm_module_new(store, &binary); + if (!module) { + printf("> Error compiling module!\n"); + return 1; + } + + wasm_byte_vec_delete(&binary); + + // 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)); + own wasm_func_t* callback_func = + 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) }; + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); + if (!instance) { + printf("> Error instantiating module!\n"); + return 1; + } + + wasm_func_delete(callback_func); + wasm_module_delete(module); + + // Extract export. + printf("Extracting exports...\n"); + own wasm_extern_vec_t exports; + wasm_instance_exports(instance, &exports); + size_t i = 0; + wasm_global_t* global = get_export_global(&exports, i++); + wasm_table_t* table = get_export_table(&exports, i++); + wasm_func_t* global_set = get_export_func(&exports, i++); + wasm_func_t* global_get = get_export_func(&exports, i++); + wasm_func_t* table_set = get_export_func(&exports, i++); + wasm_func_t* table_get = get_export_func(&exports, i++); + wasm_func_t* func_call = get_export_func(&exports, i++); + + wasm_instance_delete(instance); + + // Create host references. + printf("Creating host references...\n"); + own wasm_ref_t* host1 = wasm_foreign_as_ref(wasm_foreign_new(store)); + own wasm_ref_t* host2 = wasm_foreign_as_ref(wasm_foreign_new(store)); + wasm_ref_set_host_info(host1, (void*)1); + wasm_ref_set_host_info(host2, (void*)2); + + // Some sanity checks. + check(NULL, NULL); + check(wasm_ref_copy(host1), host1); + check(wasm_ref_copy(host2), host2); + + own wasm_val_t val; + val.kind = WASM_ANYREF; + val.of.ref = wasm_ref_copy(host1); + check(wasm_ref_copy(val.of.ref), host1); + own wasm_ref_t* ref = val.of.ref; + check(wasm_ref_copy(ref), host1); + wasm_val_delete(&val); + + // Interact. + printf("Accessing global...\n"); + check(call_v_r(global_get), NULL); + call_r_v(global_set, host1); + check(call_v_r(global_get), host1); + call_r_v(global_set, host2); + check(call_v_r(global_get), host2); + call_r_v(global_set, NULL); + check(call_v_r(global_get), NULL); + + wasm_global_get(global, &val); + assert(val.kind == WASM_ANYREF); + check(val.of.ref, NULL); + val.of.ref = host2; + wasm_global_set(global, &val); + check(call_v_r(global_get), host2); + wasm_global_get(global, &val); + assert(val.kind == WASM_ANYREF); + check(val.of.ref, host2); + + printf("Accessing table...\n"); + check(call_i_r(table_get, 0), NULL); + check(call_i_r(table_get, 1), NULL); + call_ir_v(table_set, 0, host1); + call_ir_v(table_set, 1, host2); + check(call_i_r(table_get, 0), host1); + check(call_i_r(table_get, 1), host2); + call_ir_v(table_set, 0, NULL); + check(call_i_r(table_get, 0), NULL); + + check(wasm_table_get(table, 2), NULL); + wasm_table_set(table, 2, host1); + check(call_i_r(table_get, 2), host1); + check(wasm_table_get(table, 2), host1); + + printf("Accessing function...\n"); + check(call_r_r(func_call, NULL), NULL); + check(call_r_r(func_call, host1), host1); + check(call_r_r(func_call, host2), host2); + + wasm_ref_delete(host1); + wasm_ref_delete(host2); + + wasm_extern_vec_delete(&exports); + + // Shut down. + printf("Shutting down...\n"); + wasm_store_delete(store); + wasm_engine_delete(engine); + + // All done. + printf("Done.\n"); + return 0; +} diff --git a/deps/v8/third_party/wasm-api/example/hostref.cc b/deps/v8/third_party/wasm-api/example/hostref.cc new file mode 100644 index 0000000000..74e1f119d3 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/hostref.cc @@ -0,0 +1,232 @@ +#include <iostream> +#include <fstream> +#include <cstdlib> +#include <string> +#include <cinttypes> + +#include "wasm.hh" + + +// A function to be called from Wasm code. +auto callback( + const wasm::Val args[], wasm::Val results[] +) -> wasm::own<wasm::Trap> { + std::cout << "Calling back..." << 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<wasm::Extern>& 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; + exit(1); + } + return exports[i]->func(); +} + +auto get_export_global(wasm::ownvec<wasm::Extern>& exports, size_t i) -> wasm::Global* { + if (exports.size() <= i || !exports[i]->global()) { + std::cout << "> Error accessing global export " << i << "!" << std::endl; + exit(1); + } + return exports[i]->global(); +} + +auto get_export_table(wasm::ownvec<wasm::Extern>& exports, size_t i) -> wasm::Table* { + if (exports.size() <= i || !exports[i]->table()) { + std::cout << "> Error accessing table export " << i << "!" << std::endl; + exit(1); + } + 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::Ref>())}; + if (func->call(args, nullptr)) { + std::cout << "> Error calling function!" << std::endl; + exit(1); + } + std::cout << "okay" << std::endl; +} + +auto call_v_r(const wasm::Func* func) -> wasm::own<wasm::Ref> { + std::cout << "call_v_r... " << std::flush; + wasm::Val results[1]; + if (func->call(nullptr, results)) { + std::cout << "> Error calling function!" << std::endl; + exit(1); + } + std::cout << "okay" << std::endl; + return results[0].release_ref(); +} + +auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) -> wasm::own<wasm::Ref> { + std::cout << "call_r_r... " << std::flush; + wasm::Val args[1] = {wasm::Val::ref(ref ? ref->copy() : wasm::own<wasm::Ref>())}; + wasm::Val results[1]; + if (func->call(args, results)) { + std::cout << "> Error calling function!" << std::endl; + exit(1); + } + std::cout << "okay" << std::endl; + return results[0].release_ref(); +} + +void call_ir_v(const wasm::Func* func, int32_t i, const wasm::Ref* ref) { + std::cout << "call_ir_v... " << std::flush; + wasm::Val args[2] = {wasm::Val::i32(i), wasm::Val::ref(ref ? ref->copy() : wasm::own<wasm::Ref>())}; + if (func->call(args, nullptr)) { + std::cout << "> Error calling function!" << std::endl; + exit(1); + } + std::cout << "okay" << std::endl; +} + +auto call_i_r(const wasm::Func* func, int32_t i) -> wasm::own<wasm::Ref> { + std::cout << "call_i_r... " << std::flush; + wasm::Val args[1] = {wasm::Val::i32(i)}; + wasm::Val results[1]; + if (func->call(args, results)) { + std::cout << "> Error calling function!" << std::endl; + exit(1); + } + std::cout << "okay" << std::endl; + return results[0].release_ref(); +} + +void check(wasm::own<wasm::Ref> 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; + exit(1); + } +} + +void run() { + // Initialize. + std::cout << "Initializing..." << std::endl; + auto engine = wasm::Engine::make(); + auto store_ = wasm::Store::make(engine.get()); + auto store = store_.get(); + + // Load binary. + std::cout << "Loading binary..." << std::endl; + std::ifstream file("hostref.wasm"); + file.seekg(0, std::ios_base::end); + auto file_size = file.tellg(); + file.seekg(0); + auto binary = wasm::vec<byte_t>::make_uninitialized(file_size); + file.read(binary.get(), file_size); + file.close(); + if (file.fail()) { + std::cout << "> Error loading module!" << std::endl; + return; + } + + // Compile. + std::cout << "Compiling module..." << std::endl; + auto module = wasm::Module::make(store, binary); + if (!module) { + std::cout << "> Error compiling module!" << std::endl; + return; + } + + // Create external callback function. + std::cout << "Creating callback..." << std::endl; + auto callback_type = wasm::FuncType::make( + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::ANYREF)), + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::ANYREF)) + ); + auto callback_func = wasm::Func::make(store, callback_type.get(), callback); + + // Instantiate. + std::cout << "Instantiating module..." << std::endl; + wasm::Extern* imports[] = {callback_func.get()}; + auto instance = wasm::Instance::make(store, module.get(), imports); + if (!instance) { + std::cout << "> Error instantiating module!" << std::endl; + return; + } + + // Extract export. + std::cout << "Extracting exports..." << std::endl; + auto exports = instance->exports(); + size_t i = 0; + auto global = get_export_global(exports, i++); + auto table = get_export_table(exports, i++); + auto global_set = get_export_func(exports, i++); + auto global_get = get_export_func(exports, i++); + auto table_set = get_export_func(exports, i++); + auto table_get = get_export_func(exports, i++); + auto func_call = get_export_func(exports, i++); + + // Create host references. + std::cout << "Creating host references..." << std::endl; + auto host1 = wasm::Foreign::make(store); + auto host2 = wasm::Foreign::make(store); + host1->set_host_info(reinterpret_cast<void*>(1)); + host2->set_host_info(reinterpret_cast<void*>(2)); + + // Some sanity checks. + check(nullptr, nullptr); + check(host1->copy(), host1.get()); + check(host2->copy(), host2.get()); + + wasm::Val val = wasm::Val::ref(host1->copy()); + check(val.ref()->copy(), host1.get()); + auto ref = val.release_ref(); + assert(val.ref() == nullptr); + check(ref->copy(), host1.get()); + + // Interact. + std::cout << "Accessing global..." << std::endl; + check(call_v_r(global_get), nullptr); + call_r_v(global_set, host1.get()); + check(call_v_r(global_get), host1.get()); + call_r_v(global_set, host2.get()); + check(call_v_r(global_get), host2.get()); + call_r_v(global_set, nullptr); + check(call_v_r(global_get), nullptr); + + check(global->get().release_ref(), nullptr); + global->set(wasm::Val(host2->copy())); + check(call_v_r(global_get), host2.get()); + check(global->get().release_ref(), host2.get()); + + std::cout << "Accessing table..." << std::endl; + check(call_i_r(table_get, 0), nullptr); + check(call_i_r(table_get, 1), nullptr); + call_ir_v(table_set, 0, host1.get()); + call_ir_v(table_set, 1, host2.get()); + check(call_i_r(table_get, 0), host1.get()); + check(call_i_r(table_get, 1), host2.get()); + call_ir_v(table_set, 0, nullptr); + check(call_i_r(table_get, 0), nullptr); + + check(table->get(2), nullptr); + table->set(2, host1.get()); + check(call_i_r(table_get, 2), host1.get()); + check(table->get(2), host1.get()); + + std::cout << "Accessing function..." << std::endl; + check(call_r_r(func_call, nullptr), nullptr); + check(call_r_r(func_call, host1.get()), host1.get()); + check(call_r_r(func_call, host2.get()), host2.get()); + + // Shut down. + std::cout << "Shutting down..." << std::endl; +} + + +int main(int argc, const char* argv[]) { + run(); + std::cout << "Done." << std::endl; + return 0; +} + diff --git a/deps/v8/third_party/wasm-api/example/hostref.wasm b/deps/v8/third_party/wasm-api/example/hostref.wasm Binary files differnew file mode 100644 index 0000000000..7bfc7288e9 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/hostref.wasm diff --git a/deps/v8/third_party/wasm-api/example/hostref.wat b/deps/v8/third_party/wasm-api/example/hostref.wat new file mode 100644 index 0000000000..4d14ba6ae8 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/hostref.wat @@ -0,0 +1,24 @@ +(module + (import "" "f" (func $fun (param anyref) (result anyref))) + + (global $glob (export "global") (mut anyref) (ref.null)) + (table $tab (export "table") 10 anyref) + + (func (export "global.set") (param $r anyref) + (global.set $glob (local.get $r)) + ) + (func (export "global.get") (result anyref) + (global.get $glob) + ) + + (func (export "table.set") (param $i i32) (param $r anyref) + (table.set $tab (local.get $i) (local.get $r)) + ) + (func (export "table.get") (param $i i32) (result anyref) + (table.get $tab (local.get $i)) + ) + + (func (export "func.call") (param $r anyref) (result anyref) + (call $fun (local.get $r)) + ) +) diff --git a/deps/v8/third_party/wasm-api/example/memory.c b/deps/v8/third_party/wasm-api/example/memory.c index 64b0f86b51..2c020c4597 100644 --- a/deps/v8/third_party/wasm-api/example/memory.c +++ b/deps/v8/third_party/wasm-api/example/memory.c @@ -132,7 +132,8 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - own wasm_instance_t* instance = wasm_instance_new(store, module, NULL); + own wasm_instance_t* instance = + wasm_instance_new(store, module, NULL, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -150,6 +151,11 @@ int main(int argc, const char* argv[]) { wasm_module_delete(module); + // Try cloning. + own wasm_memory_t* copy = wasm_memory_copy(memory); + assert(wasm_memory_same(memory, copy)); + wasm_memory_delete(copy); + // Check initial memory. printf("Checking memory...\n"); check(wasm_memory_size(memory) == 2); diff --git a/deps/v8/third_party/wasm-api/example/memory.cc b/deps/v8/third_party/wasm-api/example/memory.cc index fb50565c85..4094accd8d 100644 --- a/deps/v8/third_party/wasm-api/example/memory.cc +++ b/deps/v8/third_party/wasm-api/example/memory.cc @@ -7,7 +7,7 @@ #include "wasm.hh" -auto get_export_memory(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Memory* { +auto get_export_memory(wasm::ownvec<wasm::Extern>& 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,7 @@ auto get_export_memory(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Mem return exports[i]->memory(); } -auto get_export_func(const wasm::vec<wasm::Extern*>& exports, size_t i) -> const wasm::Func* { +auto get_export_func(const wasm::ownvec<wasm::Extern>& 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); @@ -79,7 +79,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -87,7 +87,7 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Instantiate. @@ -95,7 +95,7 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), nullptr); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -107,6 +107,9 @@ void run() { auto load_func = get_export_func(exports, i++); auto store_func = get_export_func(exports, i++); + // Try cloning. + assert(memory->copy()->same(memory)); + // Check initial memory. std::cout << "Checking memory..." << std::endl; check(memory->size(), 2u); diff --git a/deps/v8/third_party/wasm-api/example/multi.c b/deps/v8/third_party/wasm-api/example/multi.c new file mode 100644 index 0000000000..7bd4676bae --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/multi.c @@ -0,0 +1,154 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> + +#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[] +) { + 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("\n"); + + wasm_val_copy(&results[0], &args[0]); + return NULL; +} + + +// A function closure. +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); + + results[0].kind = WASM_I32; + results[0].of.i32 = (int32_t)i; + return NULL; +} + + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + // Load binary. + printf("Loading binary...\n"); + FILE* file = fopen("multi.wasm", "r"); + if (!file) { + printf("> Error loading module!\n"); + return 1; + } + fseek(file, 0L, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0L, SEEK_SET); + wasm_byte_vec_t binary; + wasm_byte_vec_new_uninitialized(&binary, file_size); + if (fread(binary.data, file_size, 1, file) != 1) { + printf("> Error loading module!\n"); + return 1; + } + fclose(file); + + // Compile. + printf("Compiling module...\n"); + own wasm_module_t* module = wasm_module_new(store, &binary); + if (!module) { + printf("> Error compiling module!\n"); + return 1; + } + + wasm_byte_vec_delete(&binary); + + // 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() + }; + 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_functype_delete(callback_type); + + // Instantiate. + 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); + if (!instance) { + printf("> Error instantiating module!\n"); + return 1; + } + + wasm_func_delete(callback_func); + + // Extract export. + printf("Extracting export...\n"); + own wasm_extern_vec_t exports; + wasm_instance_exports(instance, &exports); + if (exports.size == 0) { + printf("> Error accessing exports!\n"); + return 1; + } + const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]); + if (run_func == NULL) { + printf("> Error accessing export!\n"); + return 1; + } + + wasm_module_delete(module); + wasm_instance_delete(instance); + + // Call. + printf("Calling export...\n"); + wasm_val_t args[4]; + args[0].kind = WASM_I32; + args[0].of.i32 = 1; + args[1].kind = WASM_I64; + args[1].of.i64 = 2; + args[2].kind = WASM_I64; + args[2].of.i64 = 3; + args[3].kind = WASM_I32; + args[3].of.i32 = 4; + wasm_val_t results[4]; + if (wasm_func_call(run_func, args, results)) { + printf("> Error calling function!\n"); + return 1; + } + + wasm_extern_vec_delete(&exports); + + // 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); + + assert(results[0].of.i32 == 4); + assert(results[1].of.i64 == 3); + assert(results[2].of.i64 == 2); + assert(results[3].of.i32 == 1); + + // Shut down. + printf("Shutting down...\n"); + wasm_store_delete(store); + wasm_engine_delete(engine); + + // All done. + printf("Done.\n"); + return 0; +} diff --git a/deps/v8/third_party/wasm-api/example/multi.cc b/deps/v8/third_party/wasm-api/example/multi.cc new file mode 100644 index 0000000000..5ed4c9b771 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/multi.cc @@ -0,0 +1,118 @@ +#include <iostream> +#include <fstream> +#include <cstdlib> +#include <string> +#include <cinttypes> + +#include "wasm.hh" + +// A function to be called from Wasm code. +auto callback( + const wasm::Val args[], wasm::Val results[] +) -> wasm::own<wasm::Trap> { + std::cout << "Calling back..." << std::endl; + std::cout << "> " << args[0].i32(); + std::cout << " " << args[1].i64(); + std::cout << " " << args[2].i64(); + std::cout << " " << args[3].i32() << std::endl; + results[0] = args[3].copy(); + results[1] = args[1].copy(); + results[2] = args[2].copy(); + results[3] = args[0].copy(); + return nullptr; +} + + +void run() { + // Initialize. + std::cout << "Initializing..." << std::endl; + auto engine = wasm::Engine::make(); + auto store_ = wasm::Store::make(engine.get()); + auto store = store_.get(); + + // Load binary. + std::cout << "Loading binary..." << std::endl; + std::ifstream file("multi.wasm"); + file.seekg(0, std::ios_base::end); + auto file_size = file.tellg(); + file.seekg(0); + auto binary = wasm::vec<byte_t>::make_uninitialized(file_size); + file.read(binary.get(), file_size); + file.close(); + if (file.fail()) { + std::cout << "> Error loading module!" << std::endl; + exit(1); + } + + // Compile. + std::cout << "Compiling module..." << std::endl; + auto module = wasm::Module::make(store, binary); + if (!module) { + std::cout << "> Error compiling module!" << std::endl; + exit(1); + } + + // Create external print functions. + std::cout << "Creating callback..." << std::endl; + auto tuple = wasm::ownvec<wasm::ValType>::make( + 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()); + auto callback_func = wasm::Func::make(store, callback_type.get(), callback); + + // Instantiate. + std::cout << "Instantiating module..." << std::endl; + wasm::Extern* imports[] = {callback_func.get()}; + auto instance = wasm::Instance::make(store, module.get(), imports); + if (!instance) { + std::cout << "> Error instantiating module!" << std::endl; + exit(1); + } + + // 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()) { + std::cout << "> Error accessing export!" << std::endl; + exit(1); + } + auto run_func = exports[0]->func(); + + // 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 results[4]; + if (wasm::own<wasm::Trap> trap = run_func->call(args, results)) { + std::cout << "> Error calling function! " << trap->message().get() << std::endl; + exit(1); + } + + // Print result. + std::cout << "Printing result..." << std::endl; + std::cout << "> " << results[0].i32(); + std::cout << " " << results[1].i64(); + std::cout << " " << results[2].i64(); + std::cout << " " << results[3].i32() << std::endl; + + assert(results[0].i32() == 4); + assert(results[1].i64() == 3); + assert(results[2].i64() == 2); + assert(results[3].i32() == 1); + + // Shut down. + std::cout << "Shutting down..." << std::endl; +} + + +int main(int argc, const char* argv[]) { + run(); + std::cout << "Done." << std::endl; + return 0; +} + diff --git a/deps/v8/third_party/wasm-api/example/multi.wasm b/deps/v8/third_party/wasm-api/example/multi.wasm Binary files differnew file mode 100644 index 0000000000..bff0143f3f --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/multi.wasm diff --git a/deps/v8/third_party/wasm-api/example/multi.wat b/deps/v8/third_party/wasm-api/example/multi.wat new file mode 100644 index 0000000000..e7fb331125 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/multi.wat @@ -0,0 +1,7 @@ +(module + (func $f (import "" "f") (param i32 i64 i64 i32) (result i32 i64 i64 i32)) + + (func $g (export "g") (param i32 i64 i64 i32) (result i32 i64 i64 i32) + (call $f (local.get 0) (local.get 2) (local.get 1) (local.get 3)) + ) +) diff --git a/deps/v8/third_party/wasm-api/example/reflect.c b/deps/v8/third_party/wasm-api/example/reflect.c index a210a85c15..15e0165d19 100644 --- a/deps/v8/third_party/wasm-api/example/reflect.c +++ b/deps/v8/third_party/wasm-api/example/reflect.c @@ -45,28 +45,32 @@ 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(" -> "); print_valtypes(wasm_functype_results(functype)); } break; case WASM_EXTERN_GLOBAL: { - const wasm_globaltype_t* globaltype = wasm_externtype_as_globaltype_const(type); + const wasm_globaltype_t* globaltype = + wasm_externtype_as_globaltype_const(type); printf("global "); print_mutability(wasm_globaltype_mutability(globaltype)); printf(" "); print_valtype(wasm_globaltype_content(globaltype)); } break; case WASM_EXTERN_TABLE: { - const wasm_tabletype_t* tabletype = wasm_externtype_as_tabletype_const(type); + const wasm_tabletype_t* tabletype = + wasm_externtype_as_tabletype_const(type); printf("table "); print_limits(wasm_tabletype_limits(tabletype)); printf(" "); print_valtype(wasm_tabletype_element(tabletype)); } break; case WASM_EXTERN_MEMORY: { - const wasm_memorytype_t* memorytype = wasm_externtype_as_memorytype_const(type); + const wasm_memorytype_t* memorytype = + wasm_externtype_as_memorytype_const(type); printf("memory "); print_limits(wasm_memorytype_limits(memorytype)); } break; @@ -114,7 +118,7 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - own wasm_instance_t* instance = wasm_instance_new(store, module, NULL); + own wasm_instance_t* instance = wasm_instance_new(store, module, NULL, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -129,7 +133,8 @@ int main(int argc, const char* argv[]) { assert(exports.size == export_types.size); 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]))); + assert(wasm_extern_kind(exports.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/deps/v8/third_party/wasm-api/example/reflect.cc b/deps/v8/third_party/wasm-api/example/reflect.cc index c04b9e4d4e..e0f8ba6856 100644 --- a/deps/v8/third_party/wasm-api/example/reflect.cc +++ b/deps/v8/third_party/wasm-api/example/reflect.cc @@ -33,7 +33,7 @@ auto operator<<(std::ostream& out, const wasm::ValType& type) -> std::ostream& { return out; } -auto operator<<(std::ostream& out, const wasm::vec<wasm::ValType*>& types) -> std::ostream& { +auto operator<<(std::ostream& out, const wasm::ownvec<wasm::ValType>& types) -> std::ostream& { bool first = true; for (size_t i = 0; i < types.size(); ++i) { if (first) { @@ -88,7 +88,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -96,7 +96,7 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Instantiate. @@ -104,7 +104,7 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), nullptr); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract exports. diff --git a/deps/v8/third_party/wasm-api/example/serialize.c b/deps/v8/third_party/wasm-api/example/serialize.c index 8c7efc2ee9..4522c00dff 100644 --- a/deps/v8/third_party/wasm-api/example/serialize.c +++ b/deps/v8/third_party/wasm-api/example/serialize.c @@ -77,7 +77,8 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating deserialized module...\n"); const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) }; - own wasm_instance_t* instance = wasm_instance_new(store, deserialized, imports); + own wasm_instance_t* instance = + wasm_instance_new(store, deserialized, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; diff --git a/deps/v8/third_party/wasm-api/example/serialize.cc b/deps/v8/third_party/wasm-api/example/serialize.cc index 895ef396e0..7f74edba76 100644 --- a/deps/v8/third_party/wasm-api/example/serialize.cc +++ b/deps/v8/third_party/wasm-api/example/serialize.cc @@ -10,7 +10,7 @@ // A function to be called from Wasm code. auto hello_callback( const wasm::Val args[], wasm::Val results[] -) -> wasm::own<wasm::Trap*> { +) -> wasm::own<wasm::Trap> { std::cout << "Calling back..." << std::endl; std::cout << "> Hello world!" << std::endl; return nullptr; @@ -35,7 +35,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -43,7 +43,7 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Serialize module. @@ -55,13 +55,13 @@ void run() { auto deserialized = wasm::Module::deserialize(store, serialized); if (!deserialized) { std::cout << "> Error deserializing module!" << std::endl; - return; + exit(1); } // Create external print functions. std::cout << "Creating callback..." << std::endl; auto hello_type = wasm::FuncType::make( - wasm::vec<wasm::ValType*>::make(), wasm::vec<wasm::ValType*>::make() + wasm::ownvec<wasm::ValType>::make(), wasm::ownvec<wasm::ValType>::make() ); auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback); @@ -71,7 +71,7 @@ void run() { auto instance = wasm::Instance::make(store, deserialized.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -79,15 +79,15 @@ void run() { auto exports = instance->exports(); if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { std::cout << "> Error accessing export!" << std::endl; - return; + exit(1); } auto run_func = exports[0]->func(); // Call. std::cout << "Calling export..." << std::endl; - if (! run_func->call()) { + if (run_func->call()) { std::cout << "> Error calling function!" << std::endl; - return; + exit(1); } // Shut down. diff --git a/deps/v8/third_party/wasm-api/example/start.c b/deps/v8/third_party/wasm-api/example/start.c new file mode 100644 index 0000000000..42fa317490 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/start.c @@ -0,0 +1,105 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> + +#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) + ); +} + + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + // Load binary. + printf("Loading binary...\n"); + FILE* file = fopen("start.wasm", "r"); + if (!file) { + printf("> Error loading module!\n"); + return 1; + } + fseek(file, 0L, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0L, SEEK_SET); + wasm_byte_vec_t binary; + wasm_byte_vec_new_uninitialized(&binary, file_size); + if (fread(binary.data, file_size, 1, file) != 1) { + printf("> Error loading module!\n"); + return 1; + } + fclose(file); + + // Compile. + printf("Compiling module...\n"); + own wasm_module_t* module = wasm_module_new(store, &binary); + if (!module) { + printf("> Error compiling module!\n"); + return 1; + } + + wasm_byte_vec_delete(&binary); + + // Instantiate. + printf("Instantiating module...\n"); + own wasm_trap_t* trap = NULL; + own wasm_instance_t* instance = + wasm_instance_new(store, module, NULL, &trap); + if (instance || !trap) { + printf("> Error instantiating module, expected trap!\n"); + return 1; + } + + wasm_module_delete(module); + + // Print result. + printf("Printing message...\n"); + own wasm_name_t message; + wasm_trap_message(trap, &message); + printf("> %s\n", message.data); + + printf("Printing origin...\n"); + own wasm_frame_t* frame = wasm_trap_origin(trap); + if (frame) { + print_frame(frame); + wasm_frame_delete(frame); + } else { + printf("> Empty origin.\n"); + } + + printf("Printing trace...\n"); + own wasm_frame_vec_t trace; + wasm_trap_trace(trap, &trace); + if (trace.size > 0) { + for (size_t i = 0; i < trace.size; ++i) { + print_frame(trace.data[i]); + } + } else { + printf("> Empty trace.\n"); + } + + wasm_frame_vec_delete(&trace); + wasm_trap_delete(trap); + wasm_name_delete(&message); + + // Shut down. + printf("Shutting down...\n"); + wasm_store_delete(store); + wasm_engine_delete(engine); + + // All done. + printf("Done.\n"); + return 0; +} diff --git a/deps/v8/third_party/wasm-api/example/start.cc b/deps/v8/third_party/wasm-api/example/start.cc new file mode 100644 index 0000000000..71d6fd25ad --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/start.cc @@ -0,0 +1,88 @@ +#include <iostream> +#include <fstream> +#include <cstdlib> +#include <string> +#include <cinttypes> + +#include "wasm.hh" + + +void print_frame(const wasm::Frame* frame) { + std::cout << "> " << frame->instance(); + std::cout << " @ 0x" << std::hex << frame->module_offset(); + std::cout << " = " << frame->func_index(); + std::cout << ".0x" << std::hex << frame->func_offset() << std::endl; +} + + +void run() { + // Initialize. + std::cout << "Initializing..." << std::endl; + auto engine = wasm::Engine::make(); + auto store_ = wasm::Store::make(engine.get()); + auto store = store_.get(); + + // Load binary. + std::cout << "Loading binary..." << std::endl; + std::ifstream file("start.wasm"); + file.seekg(0, std::ios_base::end); + auto file_size = file.tellg(); + file.seekg(0); + auto binary = wasm::vec<byte_t>::make_uninitialized(file_size); + file.read(binary.get(), file_size); + file.close(); + if (file.fail()) { + std::cout << "> Error loading module!" << std::endl; + exit(1); + } + + // Compile. + std::cout << "Compiling module..." << std::endl; + auto module = wasm::Module::make(store, binary); + if (!module) { + std::cout << "> Error compiling module!" << std::endl; + exit(1); + } + + // Instantiate. + std::cout << "Instantiating module..." << std::endl; + wasm::own<wasm::Trap> trap; + auto instance = wasm::Instance::make(store, module.get(), nullptr, &trap); + if (instance || !trap) { + std::cout << "> Error instantiating module, expected trap!" << std::endl; + exit(1); + } + + // Print result. + std::cout << "Printing message..." << std::endl; + std::cout << "> " << trap->message().get() << std::endl; + + std::cout << "Printing origin..." << std::endl; + auto frame = trap->origin(); + if (frame) { + print_frame(frame.get()); + } else { + std::cout << "> Empty origin." << std::endl; + } + + std::cout << "Printing trace..." << std::endl; + auto trace = trap->trace(); + if (trace.size() > 0) { + for (size_t i = 0; i < trace.size(); ++i) { + print_frame(trace[i].get()); + } + } else { + std::cout << "> Empty trace." << std::endl; + } + + // Shut down. + std::cout << "Shutting down..." << std::endl; +} + + +int main(int argc, const char* argv[]) { + run(); + std::cout << "Done." << std::endl; + return 0; +} + diff --git a/deps/v8/third_party/wasm-api/example/start.wasm b/deps/v8/third_party/wasm-api/example/start.wasm Binary files differnew file mode 100644 index 0000000000..90cba2107d --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/start.wasm diff --git a/deps/v8/third_party/wasm-api/example/start.wat b/deps/v8/third_party/wasm-api/example/start.wat new file mode 100644 index 0000000000..eb95116a49 --- /dev/null +++ b/deps/v8/third_party/wasm-api/example/start.wat @@ -0,0 +1,4 @@ +(module + (func $start (unreachable)) + (start $start) +) diff --git a/deps/v8/third_party/wasm-api/example/table.c b/deps/v8/third_party/wasm-api/example/table.c index 8fec71f23f..0ff6617f72 100644 --- a/deps/v8/third_party/wasm-api/example/table.c +++ b/deps/v8/third_party/wasm-api/example/table.c @@ -110,7 +110,8 @@ int main(int argc, const char* argv[]) { // Instantiate. printf("Instantiating module...\n"); - own wasm_instance_t* instance = wasm_instance_new(store, module, NULL); + own wasm_instance_t* instance = + wasm_instance_new(store, module, NULL, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -135,6 +136,11 @@ int main(int argc, const char* argv[]) { wasm_functype_delete(neg_type); + // Try cloning. + own wasm_table_t* copy = wasm_table_copy(table); + assert(wasm_table_same(table, copy)); + wasm_table_delete(copy); + // Check initial table. printf("Checking table...\n"); check(wasm_table_size(table) == 2); diff --git a/deps/v8/third_party/wasm-api/example/table.cc b/deps/v8/third_party/wasm-api/example/table.cc index cb669cdb16..b19d37763b 100644 --- a/deps/v8/third_party/wasm-api/example/table.cc +++ b/deps/v8/third_party/wasm-api/example/table.cc @@ -10,14 +10,14 @@ // A function to be called from Wasm code. auto neg_callback( const wasm::Val args[], wasm::Val results[] -) -> wasm::own<wasm::Trap*> { +) -> wasm::own<wasm::Trap> { std::cout << "Calling back..." << std::endl; results[0] = wasm::Val(-args[0].i32()); return nullptr; } -auto get_export_table(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Table* { +auto get_export_table(wasm::ownvec<wasm::Extern>& 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 +25,7 @@ auto get_export_table(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Tabl return exports[i]->table(); } -auto get_export_func(const wasm::vec<wasm::Extern*>& exports, size_t i) -> const wasm::Func* { +auto get_export_func(const wasm::ownvec<wasm::Extern>& 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); @@ -87,7 +87,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -95,7 +95,7 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Instantiate. @@ -103,7 +103,7 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), nullptr); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -118,11 +118,14 @@ void run() { // Create external function. std::cout << "Creating callback..." << std::endl; auto neg_type = wasm::FuncType::make( - wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)), - wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)) + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::I32)), + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::I32)) ); auto h = wasm::Func::make(store, neg_type.get(), neg_callback); + // Try cloning. + assert(table->copy()->same(table)); + // Check initial table. std::cout << "Checking table..." << std::endl; check(table->size(), 2u); diff --git a/deps/v8/third_party/wasm-api/example/threads.c b/deps/v8/third_party/wasm-api/example/threads.c index 2f5b0f3c1f..9f9d5894a6 100644 --- a/deps/v8/third_party/wasm-api/example/threads.c +++ b/deps/v8/third_party/wasm-api/example/threads.c @@ -52,7 +52,8 @@ void* run(void* args_abs) { const wasm_extern_t* imports[] = { wasm_func_as_extern(func), wasm_global_as_extern(global), }; - own wasm_instance_t* instance = wasm_instance_new(store, module, imports); + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return NULL; diff --git a/deps/v8/third_party/wasm-api/example/threads.cc b/deps/v8/third_party/wasm-api/example/threads.cc index 48b4fcd486..3fdaded6cd 100644 --- a/deps/v8/third_party/wasm-api/example/threads.cc +++ b/deps/v8/third_party/wasm-api/example/threads.cc @@ -11,7 +11,7 @@ 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<wasm::Trap*> { +) -> wasm::own<wasm::Trap> { assert(args[0].kind() == wasm::I32); std::lock_guard<std::mutex>(*reinterpret_cast<std::mutex*>(env)); std::cout << "Thread " << args[0].i32() << " running..." << std::endl; @@ -33,7 +33,7 @@ void run( if (!module) { std::lock_guard<std::mutex> lock(*mutex); std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Run the example N times. @@ -42,8 +42,8 @@ void run( // Create imports. auto func_type = wasm::FuncType::make( - wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)), - wasm::vec<wasm::ValType*>::make() + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::I32)), + wasm::ownvec<wasm::ValType>::make() ); auto func = wasm::Func::make(store, func_type.get(), callback, mutex); @@ -58,7 +58,7 @@ void run( if (!instance) { std::lock_guard<std::mutex> lock(*mutex); std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -66,7 +66,7 @@ void run( if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) { std::lock_guard<std::mutex> lock(*mutex); std::cout << "> Error accessing export!" << std::endl; - return; + exit(1); } auto run_func = exports[0]->func(); diff --git a/deps/v8/third_party/wasm-api/example/trap.c b/deps/v8/third_party/wasm-api/example/trap.c index 74620dce3b..975d6f8599 100644 --- a/deps/v8/third_party/wasm-api/example/trap.c +++ b/deps/v8/third_party/wasm-api/example/trap.c @@ -20,6 +20,16 @@ own wasm_trap_t* fail_callback( } +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) + ); +} + + int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); @@ -56,15 +66,18 @@ 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()); - own wasm_func_t* fail_func = wasm_func_new_with_env(store, fail_type, fail_callback, store, NULL); + own wasm_functype_t* fail_type = + 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_functype_delete(fail_type); // Instantiate. printf("Instantiating module...\n"); const wasm_extern_t* imports[] = { wasm_func_as_extern(fail_func) }; - own wasm_instance_t* instance = wasm_instance_new(store, module, imports); + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -94,8 +107,8 @@ int main(int argc, const char* argv[]) { printf("Calling export %d...\n", i); own wasm_trap_t* trap = wasm_func_call(func, NULL, NULL); - if (! trap) { - printf("> Error calling function!\n"); + if (!trap) { + printf("> Error calling function, expected trap!\n"); return 1; } @@ -104,6 +117,27 @@ int main(int argc, const char* argv[]) { wasm_trap_message(trap, &message); printf("> %s\n", message.data); + printf("Printing origin...\n"); + own wasm_frame_t* frame = wasm_trap_origin(trap); + if (frame) { + print_frame(frame); + wasm_frame_delete(frame); + } else { + printf("> Empty origin.\n"); + } + + printf("Printing trace...\n"); + own wasm_frame_vec_t trace; + wasm_trap_trace(trap, &trace); + if (trace.size > 0) { + for (size_t i = 0; i < trace.size; ++i) { + print_frame(trace.data[i]); + } + } else { + printf("> Empty trace.\n"); + } + + wasm_frame_vec_delete(&trace); wasm_trap_delete(trap); wasm_name_delete(&message); } diff --git a/deps/v8/third_party/wasm-api/example/trap.cc b/deps/v8/third_party/wasm-api/example/trap.cc index 3311621724..3a7dcc6cff 100644 --- a/deps/v8/third_party/wasm-api/example/trap.cc +++ b/deps/v8/third_party/wasm-api/example/trap.cc @@ -9,7 +9,7 @@ // A function to be called from Wasm code. auto fail_callback( void* env, const wasm::Val args[], wasm::Val results[] -) -> wasm::own<wasm::Trap*> { +) -> wasm::own<wasm::Trap> { std::cout << "Calling back..." << std::endl; auto store = reinterpret_cast<wasm::Store*>(env); auto message = wasm::Name::make(std::string("callback abort")); @@ -17,6 +17,14 @@ auto fail_callback( } +void print_frame(const wasm::Frame* frame) { + std::cout << "> " << frame->instance(); + std::cout << " @ 0x" << std::hex << frame->module_offset(); + std::cout << " = " << frame->func_index(); + std::cout << ".0x" << std::hex << frame->func_offset() << std::endl; +} + + void run() { // Initialize. std::cout << "Initializing..." << std::endl; @@ -35,7 +43,7 @@ void run() { file.close(); if (file.fail()) { std::cout << "> Error loading module!" << std::endl; - return; + exit(1); } // Compile. @@ -43,14 +51,14 @@ void run() { auto module = wasm::Module::make(store, binary); if (!module) { std::cout << "> Error compiling module!" << std::endl; - return; + exit(1); } // Create external print functions. std::cout << "Creating callback..." << std::endl; auto fail_type = wasm::FuncType::make( - wasm::vec<wasm::ValType*>::make(), - wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)) + wasm::ownvec<wasm::ValType>::make(), + wasm::ownvec<wasm::ValType>::make(wasm::ValType::make(wasm::I32)) ); auto fail_func = wasm::Func::make(store, fail_type.get(), fail_callback, store); @@ -61,7 +69,7 @@ void run() { auto instance = wasm::Instance::make(store, module.get(), imports); if (!instance) { std::cout << "> Error instantiating module!" << std::endl; - return; + exit(1); } // Extract export. @@ -71,7 +79,7 @@ void run() { 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; - return; + exit(1); } // Call. @@ -79,12 +87,30 @@ void run() { std::cout << "Calling export " << i << "..." << std::endl; auto trap = exports[i]->func()->call(); if (!trap) { - std::cout << "> Error calling function!" << std::endl; - return; + std::cout << "> Error calling function, expected trap!" << std::endl; + exit(1); } std::cout << "Printing message..." << std::endl; std::cout << "> " << trap->message().get() << std::endl; + + std::cout << "Printing origin..." << std::endl; + auto frame = trap->origin(); + if (frame) { + print_frame(frame.get()); + } else { + std::cout << "> Empty origin." << std::endl; + } + + std::cout << "Printing trace..." << std::endl; + auto trace = trap->trace(); + if (trace.size() > 0) { + for (size_t i = 0; i < trace.size(); ++i) { + print_frame(trace[i].get()); + } + } else { + std::cout << "> Empty trace." << std::endl; + } } // Shut down. |