| 81 | } |
| 82 | |
| 83 | int deserialize(wasm_byte_vec_t *buffer) { |
| 84 | // Set up our compilation context. Note that we could also work with a |
| 85 | // `wasm_config_t` here to configure what feature are enabled and various |
| 86 | // compilation settings. |
| 87 | printf("Initializing...\n"); |
| 88 | wasm_engine_t *engine = wasm_engine_new(); |
| 89 | assert(engine != NULL); |
| 90 | |
| 91 | // With an engine we can create a *store* which is a long-lived group of wasm |
| 92 | // modules. |
| 93 | wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL); |
| 94 | assert(store != NULL); |
| 95 | wasmtime_context_t *context = wasmtime_store_context(store); |
| 96 | |
| 97 | // Deserialize compiled module. |
| 98 | printf("Deserialize module...\n"); |
| 99 | wasmtime_module_t *module = NULL; |
| 100 | wasmtime_error_t *error = wasmtime_module_deserialize( |
| 101 | engine, (uint8_t *)buffer->data, buffer->size, &module); |
| 102 | if (error != NULL) |
| 103 | exit_with_error("failed to compile module", error, NULL); |
| 104 | |
| 105 | // Next up we need to create the function that the wasm module imports. Here |
| 106 | // we'll be hooking up a thunk function to the `hello_callback` native |
| 107 | // function above. |
| 108 | printf("Creating callback...\n"); |
| 109 | wasm_functype_t *hello_ty = wasm_functype_new_0_0(); |
| 110 | wasmtime_func_t hello; |
| 111 | wasmtime_func_new(context, hello_ty, hello_callback, NULL, NULL, &hello); |
| 112 | wasm_functype_delete(hello_ty); |
| 113 | |
| 114 | // With our callback function we can now instantiate the compiled module, |
| 115 | // giving us an instance we can then execute exports from. Note that |
| 116 | // instantiation can trap due to execution of the `start` function, so we need |
| 117 | // to handle that here too. |
| 118 | printf("Instantiating module...\n"); |
| 119 | wasm_trap_t *trap = NULL; |
| 120 | wasmtime_instance_t instance; |
| 121 | wasmtime_extern_t imports[1]; |
| 122 | imports[0].kind = WASMTIME_EXTERN_FUNC; |
| 123 | imports[0].of.func = hello; |
| 124 | error = wasmtime_instance_new(context, module, imports, 1, &instance, &trap); |
| 125 | if (error != NULL || trap != NULL) |
| 126 | exit_with_error("failed to instantiate", error, trap); |
| 127 | wasmtime_module_delete(module); |
| 128 | |
| 129 | // Lookup our `run` export function |
| 130 | wasmtime_extern_t run; |
| 131 | bool ok = wasmtime_instance_export_get(context, &instance, "run", 3, &run); |
| 132 | assert(ok); |
| 133 | assert(run.kind == WASMTIME_EXTERN_FUNC); |
| 134 | |
| 135 | // And call it! |
| 136 | printf("Calling export...\n"); |
| 137 | error = wasmtime_func_call(context, &run.of.func, NULL, 0, NULL, 0, &trap); |
| 138 | if (error != NULL || trap != NULL) |
| 139 | exit_with_error("failed to call function", error, trap); |
| 140 | |