Advertisement
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
- #define WASM_ARRAY_LEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
- inline wasm_functype_t* wasm_functype_new_4_1(wasm_valtype_t* p1, wasm_valtype_t* p2, wasm_valtype_t* p3,
- wasm_valtype_t* p4, wasm_valtype_t* r)
- {
- wasm_valtype_t* ps[4] = {p1, p2, p3, p4};
- wasm_valtype_t* rs[1] = {r};
- wasm_valtype_vec_t params, results;
- wasm_valtype_vec_new(¶ms, WASM_ARRAY_LEN(ps), ps);
- wasm_valtype_vec_new(&results, WASM_ARRAY_LEN(rs), rs);
- return wasm_functype_new(¶ms, &results);
- }
- wasm_functype_t *__ft_i32_out_i32 = NULL;
- wasm_functype_t *__ft_i32_i32_out_i32 = NULL;
- wasm_functype_t *__ft_i32_i32_i32_i32_out_i32 = NULL;
- wasm_functype_t *__ft_i32_i64_i32_i32_out_i32 = NULL;
- void Function_Types_Init()
- {
- wasm_valtype_t* val_i32 = wasm_valtype_new(WASM_I32);
- wasm_valtype_t* val_i64 = wasm_valtype_new(WASM_I64);
- // Binding function signatures ...
- __ft_i32_out_i32 = wasm_functype_new_1_1(val_i32, val_i32);
- #if 0
- __ft_i32_i32_out_i32 = wasm_functype_new_2_1(val_i32, val_i32, val_i32);
- __ft_i32_i32_i32_i32_out_i32 = wasm_functype_new_4_1(val_i32, val_i32, val_i32, val_i32, val_i32);
- __ft_i32_i64_i32_i32_out_i32 = wasm_functype_new_4_1(val_i32, val_i64, val_i32, val_i32, val_i32);
- #endif
- wasm_valtype_delete(val_i32);
- wasm_valtype_delete(val_i64);
- }
- 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);
- #ifdef INFINITY_PLUGIN_EXPORTS
- const char *filename = "z:\\dev\\wasm\\wasmtime\\examples\\repro\\wasm\\build_d\\app.wasm";
- #else
- const char *filename = ".\\examples\\repro\\wasm\\build_d\\app.wasm";
- #endif
- FILE* file = fopen(filename, "rb");
- if (!file)
- {
- Logf("Couldn't open wasm binary");
- exit(0);
- }
- 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);
- size_t count = fread(wasm.data, 1, file_size, file);
- fclose(file);
- if (count != file_size)
- {
- Logf("Couldn't read wasm binary");
- exit(0);
- }
- wasmtime_error_t *error = NULL;
- // Now that we've got our binary web assembly we can compile our module.
- Logf("Loaded module ... size : %zu\n", file_size);
- Logf("data[1] : %x\n", wasm.data[1]);
- 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);
- Logf("FT[a].\n");
- Function_Types_Init();
- Logf("FT[b].\n");
- // 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("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);
- }
- if (out.of.i32 != (in.of.i32 + 1))
- Logf("Incorrect result or test program has changed.");
- 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("Error: %s\n", message);
- wasm_byte_vec_t error_message;
- if (error) {
- 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
Advertisement