Skip to content

Instantly share code, notes, and snippets.

@psarna

psarna/wasm.c Secret

Created October 1, 2022 12:10
Show Gist options
  • Save psarna/93cdc1c2b4de36c98db8af5bc77b1351 to your computer and use it in GitHub Desktop.
Save psarna/93cdc1c2b4de36c98db8af5bc77b1351 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <wasmtime/error.h>
#include "sqlite3.h"
#include "wasm.h"
#include "wasmtime.h"
const char fib_source[] =
"(module"
" (export \"fib\" (func $fib))"
" (func $fib (param $n i32) (result i32)"
" (if"
" (i32.lt_s"
" (get_local $n)"
" (i32.const 2)"
" )"
" (return"
" (i32.const 1)"
" )"
" )"
" (return"
" (i32.add"
" (call $fib"
" (i32.sub"
" (get_local $n)"
" (i32.const 2)"
" )"
" )"
" (call $fib"
" (i32.sub"
" (get_local $n)"
" (i32.const 1)"
" )"
" )"
" )"
" )"
" )"
")";
static void fib_but_wasm(sqlite3_context *context, int argc, sqlite3_value **argv) {
wasm_engine_t *engine = wasm_engine_new();
wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL);
wasmtime_context_t *wasm_ctx = wasmtime_store_context(store);
wasm_byte_vec_t wasm;
wasmtime_error_t *error = wasmtime_wat2wasm(fib_source, sizeof(fib_source) - 1, &wasm);
if (error) {
wasm_name_t message;
wasmtime_error_message(error, &message);
fprintf(stderr, "msg\n");
fprintf(stderr, "%s\n", message.data);
wasm_byte_vec_delete(&message);
abort();
}
// Compile & instantiate the module (should be done once)
wasmtime_module_t *module = NULL;
wasmtime_module_new(engine, (uint8_t*) wasm.data, wasm.size, &module);
wasm_byte_vec_delete(&wasm);
wasm_trap_t *trap = NULL;
wasmtime_instance_t instance;
error = wasmtime_instance_new(wasm_ctx, module, NULL, 0, &instance, &trap);
// Lookup our `fib` export function
wasmtime_extern_t fib;
bool ok = wasmtime_instance_export_get(wasm_ctx, &instance, "fib", 3, &fib);
assert(ok);
assert(fib.kind == WASMTIME_EXTERN_FUNC);
// Call it
wasmtime_val_t params[1];
params[0].kind = WASMTIME_I32;
params[0].of.i32 = sqlite3_value_int(argv[0]);;
wasmtime_val_t results[1];
error = wasmtime_func_call(wasm_ctx, &fib.of.func, params, 1, results, 1, &trap);
assert(results[0].kind == WASMTIME_I32);
sqlite3_result_int(context, results[0].of.i32);
}
int main(void) {
sqlite3 *db;
sqlite3_stmt *stmt;
sqlite3_open("/tmp/srn.db", &db);
if (!db) {
printf("Failed to open DB\n");
return 1;
}
sqlite3_create_function(db, "fib_but_wasm", 1, SQLITE_UTF8, NULL, &fib_but_wasm, NULL, NULL);
sqlite3_prepare_v2(db, "select id, fib_but_wasm(id) from t", -1, &stmt, NULL);
printf("Results:\n");
while (sqlite3_step(stmt) != SQLITE_DONE) {
assert(sqlite3_column_count(stmt) == 2);
assert(sqlite3_column_type(stmt, 0) == SQLITE_INTEGER);
assert(sqlite3_column_type(stmt, 1) == SQLITE_INTEGER);
printf("\tfib(%d) = %d\n", sqlite3_column_int(stmt, 0), sqlite3_column_int(stmt, 1));
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment