#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include "headers/wasm.h"
#include "headers/wasmer.h"
void print_wasmer_error() {
int error_len = wasmer_last_error_length();
if (error_len > 0) {
printf("Error len: `%d`\n", error_len);
char *error_str = malloc(error_len);
wasmer_last_error_message(error_str, error_len);
fprintf(stderr, "Error str: `%s`\n", error_str);
free(error_str);
}
}
int main(int argc, const char* argv[]) {
// Args check
// ./runner file.wasm func_name
if (argc <= 2) {
fprintf(stderr, "Error: argc <= 2\n");
return 1;
}
// Init
wasm_engine_t* engine = wasm_engine_new();
wasm_store_t* store = wasm_store_new(engine);
// Setup WASI
wasi_config_t* config = wasi_config_new("prog_name");
// Load binary
FILE* file = fopen(argv[1], "rb");
if (!file) {
fprintf(stderr, "Cannot open %s\nFailed to load wasm...\n", argv[1]);
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) {
fprintf(stderr, "Error: initializing module\n");
return 1;
}
fclose(file);
// Create module (Compile)
wasm_module_t* module = wasm_module_new(store, &binary);
if (!module) {
fprintf(stderr, "Error: compiling module\n");
return 1;
}
wasm_byte_vec_delete(&binary);
// Init wasi env
wasi_env_t* wasi_env = wasi_env_new(store, config);
if (!wasi_env) {
fprintf(stderr, "Error: building WASI env\n");
return 1;
}
// WASI Imports
wasm_extern_vec_t imports;
bool get_imports_result = wasi_get_imports(store, wasi_env, module, &imports);
if (!get_imports_result) {
fprintf(stderr, "Failed to getting wasi imports\n");
return 1;
}
wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL);
if (!instance) {
fprintf(stderr, "Error instantiating module\n");
print_wasmer_error();
return 1;
}
if (!wasi_env_initialize_instance(wasi_env, store, instance)) {
fprintf(stderr, "Error initializing wasi env memory");
print_wasmer_error();
return 1;
}
wasm_extern_vec_t exports;
wasm_instance_exports(instance, &exports);
wasm_exporttype_vec_t export_types;
wasm_module_exports(module, &export_types);
for (size_t i = 0; i < export_types.size; i++) {
wasm_exporttype_t* exptype = export_types.data[i];
if (wasm_externtype_kind(wasm_exporttype_type(exptype)) == WASM_EXTERN_FUNC) {
const wasm_name_t* exp_name = wasm_exporttype_name(exptype);
char *func_name = malloc(exp_name->size + 1);
for (size_t j = 0; j < exp_name->size; j++) {
func_name[j] = exp_name->data[j];
}
func_name[exp_name->size] = '\0';
if (strcmp(func_name, argv[2]) == 0) {
// hit
fprintf(stderr, "calling...\n");
wasm_val_t func_res_val[1] = { WASM_INIT_VAL };
wasm_val_vec_t func_res = WASM_ARRAY_VEC(func_res_val);
wasm_func_t* target_func = wasm_extern_as_func(exports.data[i]);
if (wasm_func_call(target_func, NULL, &func_res)) {
fprintf(stderr, "Failed calling the add function\n");
print_wasmer_error();
return 1;
}
printf("%s: %d\n", func_name, func_res_val[0].of.i32);
wasm_func_delete(target_func);
}
free(func_name);
}
}
// Shut down
wasi_env_delete(wasi_env);
wasm_module_delete(module);
wasm_instance_delete(instance);
wasm_store_delete(store);
wasm_engine_delete(engine);
fprintf(stderr, "bye\n");
}