Wasmer Engine Object File

This is an engine for the wasmer WebAssembly VM.

This engine is used to produce a native object file that can be linked against providing a sandboxed WebAssembly runtime environment for the compiled module with no need for runtime compilation.

Example of use

First we compile our WebAssembly file with Wasmer sh wasmer compile path/to/wasm/file.wasm --llvm --object-file -o my_wasm.o --header my_wasm.h

You will then see output like: Engine: objectfile Compiler: llvm Target: x86_64-apple-darwin ✔ File compiled successfully to `my_wasm.o`. ✔ Header file generated successfully at `my_wasm.h`.

Now lets create a program to link with this object file.

```C

ifdef __cplusplus

extern "C" {

endif

include "wasmer_wasm.h"

include "wasm.h"

include "my_wasm.h"

include

include

define own

ifdef __cplusplus

}

endif

void printwasmererror() { int errorlen = wasmerlasterrorlength(); printf("Error len: %d\n", errorlen); char* errorstr = (char*) malloc(errorlen); wasmerlasterrormessage(errorstr, errorlen); printf("Error str: %s\n", error_str); }

int main() { printf("Initializing...\n"); wasmconfigt* config = wasmconfignew(); wasmconfigsetengine(config, OBJECTFILE); wasmenginet* engine = wasmenginenewwithconfig(config); wasmstoret* store = wasmstorenew(engine);

    wasm_module_t* module = wasmer_object_file_engine_new(store, "qjs.wasm");
    if (! module) {
            printf("Failed to create module\n");
            print_wasmer_error();
            return -1;
    }

    // We have now finished the memory buffer book keeping and we have a valid Module.

    // In this example we're passing some JavaScript source code as a command line argument
    // to a WASI module that can evaluate JavaScript.
    wasi_config_t* wasi_config = wasi_config_new("constant_value_here");
    const char* js_string = "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));";
    wasi_config_arg(wasi_config, "--eval");
    wasi_config_arg(wasi_config, js_string);
    wasi_env_t* wasi_env = wasi_env_new(wasi_config);
    if (!wasi_env) {
            printf("> Error building WASI env!\n");
            print_wasmer_error();
            return 1;
    }

    wasm_importtype_vec_t import_types;
    wasm_module_imports(module, &import_types);
    int num_imports = import_types.size;
    wasm_extern_t** imports = (wasm_extern_t**) malloc(num_imports * sizeof(wasm_extern_t*));
    wasm_importtype_vec_delete(&import_types);

    bool get_imports_result = wasi_get_imports(store, module, wasi_env, imports);
    if (!get_imports_result) {
            printf("> Error getting WASI imports!\n");
            print_wasmer_error();
            return 1;
    }

    wasm_instance_t* instance = wasm_instance_new(store, module, (const wasm_extern_t* const*) imports, NULL);
    if (! instance) {
            printf("Failed to create instance\n");
            print_wasmer_error();
            return -1;
    }
    wasi_env_set_instance(wasi_env, instance);

    // WASI is now set up.
    own wasm_func_t* start_function = wasi_get_start_function(instance);
    if (!start_function) {
            fprintf(stderr, "`_start` function not found\n");
            print_wasmer_error();
            return -1;
    }

    fflush(stdout);
    own wasm_trap_t* trap = wasm_func_call(start_function, NULL, NULL);
    if (trap) {
            fprintf(stderr, "Trap is not NULL: TODO:\n");
            return -1;
    }

    wasm_instance_delete(instance);
    wasm_module_delete(module);
    wasm_store_delete(store);
    wasm_engine_delete(engine);
    return 0;

} ```

We save that source code into test.c and run:

sh clang -O2 -c test.c -o test.o

Now we just need to link everything together:

sh clang -O2 test.o my_wasm.o libwasmer_c_api.a

We link the object file we created with our C code, the object file we generated with Wasmer, and libwasmer_c_api together and produce an executable that can call into our compiled WebAssembly!