Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Wasmtime failure repro.
- Author: Steve Williams, Advance Software
- Compiled as a console app, Windows, functions as expect.
- Compiled as a Windows app, fails.
- */
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <wasm.h>
- #include <wasmtime.h>
- static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap);
- #define STRLEN(x) (sizeof(x)-1)
- wasm_engine_t *__engine = NULL;
- wasm_engine_t *Engine_Init(bool debug_mode)
- {
- // Configuring engine to support generating of DWARF info.
- // lldb can be used to debug program via GDB/JIT interface provided by wasmtime.
- wasm_config_t* wasm_config = wasm_config_new();
- wasmtime_config_debug_info_set(wasm_config, debug_mode);
- __engine = wasm_engine_new_with_config(wasm_config);
- return __engine;
- }
- int _export_init_fn = -1;
- #if INF_DEBUG_PROBE_STANDALONE
- #include <windows.h>
- #include <stdio.h>
- void Logf(const char *format, ...)
- {
- va_list arg_list;
- va_start(arg_list, format);
- // Do the format once to get the length.
- #if defined _WIN32 || defined _WIN64 /// COMPILER(MSVC)
- int len = _vscprintf(format, arg_list);
- #else
- char ch;
- int len = vsnprintf(&ch, 1, format, arg_list);
- // We need to call va_end() and then va_start() again here, as the
- // contents of args is undefined after the call to vsnprintf
- // according to http://man.cx/snprintf(3)
- // Not calling va_end/va_start here happens to work on lots of systems, but fails on some systems e.g. 64 bit Linux.
- va_end(arg_list);
- va_start(arg_list, format);
- #endif
- // Ensure we have enough room.
- char *tmp = malloc(len+1);
- vsprintf(tmp, format, arg_list);
- va_end(arg_list);
- MessageBoxA(NULL, tmp, "repro", MB_OK);
- free(tmp);
- }
- #else
- #define Logf printf
- #endif
- bool Analyze_Exports(wasm_module_t *module)
- {
- // Extract export.
- wasm_exporttype_vec_t export_types;
- wasm_module_exports(module, &export_types);
- if (export_types.size == 0)
- {
- Logf("Error : Module contains no exported functions.\n");
- return false;
- }
- // Scan for exports we're expecting.
- for (auto i = 0; i < export_types.size; ++i)
- {
- const wasm_externtype_t *etype = wasm_exporttype_type(export_types.data[i]);
- if (wasm_externtype_kind(etype) == WASM_EXTERN_FUNC)
- {
- const wasm_externtype_t *type_info = wasm_exporttype_type(export_types.data[i]);
- if (wasm_externtype_kind(type_info) == WASM_EXTERN_FUNC)
- {
- const wasm_name_t *id = wasm_exporttype_name(export_types.data[i]);
- if (!strncmp("app_init", id->data, STRLEN("app_init")))
- {
- const wasm_functype_t* func_type = wasm_externtype_as_functype_const(type_info);
- // Check parameters ...
- const wasm_valtype_vec_t *param_sig = wasm_functype_params(func_type);
- bool param_match = false;
- if (param_sig->size == 1)
- {
- if (wasm_valtype_kind(param_sig->data[0]) == WASM_I32)
- param_match = true;
- }
- // Check return sig ...
- const wasm_valtype_vec_t *return_sig = wasm_functype_results(func_type);
- bool return_sig_match = false;
- if (return_sig->size == 1)
- {
- if (wasm_valtype_kind(return_sig->data[0]) == WASM_I32)
- return_sig_match = true;
- }
- if (return_sig_match && param_match)
- _export_init_fn = i;
- }
- }
- }
- }
- return _export_init_fn != -1;
- }
- #define INF_WASM_VEC(x) { 1, &(x) }
- int main()
- {
- wasm_engine_t *engine = Engine_Init(true);
- FILE* file = fopen("..\\..\\examples\\repro\\wasm\\build_d\\app.wasm", "rb");
- assert(file != NULL);
- fseek(file, 0L, SEEK_END);
- size_t file_size = ftell(file);
- fseek(file, 0L, SEEK_SET);
- wasm_byte_vec_t wasm;
- wasm_byte_vec_new_uninitialized(&wasm, file_size);
- assert(fread(wasm.data, file_size, 1, file) == 1);
- fclose(file);
- wasmtime_error_t *error = NULL;
- // Now that we've got our binary web assembly we can compile our module.
- Logf("Loaded module ... size : %d\n", file_size);
- wasm_store_t *store = wasm_store_new(__engine);
- if (!store)
- {
- Logf("No store");
- return false;
- }
- wasm_module_t *module = store ? wasm_module_new(store, &wasm) : NULL;
- if (!module)
- {
- Logf("wasm_module_new failed.\n");
- exit(1);
- }
- wasm_byte_vec_delete(&wasm);
- if (error)
- exit_with_error("failed to compile module", error, NULL);
- // With our callback function we can now instantiate the compiled module,
- // giving us an instance we can then execute exports from. Note that
- // instantiation can trap due to execution of the `app_init` function, so we need
- // to handle that here too.
- Logf("Instantiating module...\n");
- wasm_trap_t *trap = NULL;
- wasm_extern_vec_t _imports = WASM_EMPTY_VEC;
- wasm_instance_t *instance = wasm_instance_new(store, module, &_imports, &trap);
- if (error|| trap)
- exit_with_error("failed to instantiate", error, trap);
- // Lookup our `run` export function
- Logf("Extracting export...\n");
- bool ok = Analyze_Exports(module);
- if (!ok)
- {
- Logf("Exports not as expected.\n");
- exit(1);
- }
- wasm_extern_vec_t exports;
- wasm_instance_exports(instance, &exports);
- wasm_func_t* init_fn = wasm_extern_as_func(exports.data[_export_init_fn]);
- if (!init_fn)
- {
- Logf(stderr, "Export function not as expected.\n");
- exit(1);
- }
- wasm_val_t in;
- in.kind = WASM_I32;
- in.of.i32 = 1;
- wasm_val_t out;
- out.kind = WASM_I32;
- out.of.i32 = 0;
- const wasm_val_vec_t _in = INF_WASM_VEC(in);
- wasm_val_vec_t _out = INF_WASM_VEC(out);
- trap = wasm_func_call(init_fn, &_in, &_out);
- if (trap)
- {
- exit_with_error("Function call fail :", NULL, trap);
- exit(1);
- }
- Logf("Input: %d\nOutput: %d\n", in.of.i32, out.of.i32);
- // TODO: Clean up
- wasm_engine_delete(engine);
- return 0;
- }
- static void exit_with_error(const char *message, wasmtime_error_t *error, wasm_trap_t *trap) {
- Logf(stderr, "error: %s\n", message);
- wasm_byte_vec_t error_message;
- if (error != NULL) {
- wasmtime_error_message(error, &error_message);
- wasmtime_error_delete(error);
- } else {
- wasm_trap_message(trap, &error_message);
- wasm_trap_delete(trap);
- }
- Logf("%.*s\n", (int) error_message.size, error_message.data);
- wasm_byte_vec_delete(&error_message);
- exit(1);
- }
- #if INF_DEBUG_PROBE_STANDALONE
- #ifdef INF_DEBUG
- #pragma comment(lib, "..\\..\\..\\..\\target\\debug\\wasmtime.dll.lib")
- #else
- #pragma comment(lib, "..\\..\\..\\..\\target\\release\\wasmtime.dll.lib")
- #endif
- #include <windows.h>
- int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
- {
- main();
- return 0;
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment