Commit fd2aae3
authored
Merge 'Allow registering and executing WebAssembly functions' from Piotr Sarna (#45)
This series implements a mechanism for registering and running Wasm
functions. The current runtime of choice is wasmtime and its
libwasmtime.so library with C bindings (but a switch to Rust should be
considered, because that's the native language of wasmtime and the only
interface which offers all of its features).
It operates on a very crude ABI (ref:#16), where ints and doubles are
passed to/from WebAssembly as is, and for strings/blobs/null it passes a
pointer to a structure:
string: [1 byte for type specification][data]
blob: [1 byte for type specification][4 bytes of size][data]
null: [1 byte for type specification]
The way it's implemented now is twofold:
There's an internal run_wasm function, capable of running WebAssembly
and translating the parameter types from and to the Wasm module A
dynamic lookup table, currently a regular SQL table: CREATE TABLE
libsql_wasm_func_table(name text PRIMARY KEY, body text). The table can
be initialized from C code by calling
libsql_try_initialize_wasm_func_table() or from shell by using a
.init_wasm_func_table command.
After creating and filling the new meta-table, when a function call is
used in a statement, e.g. SELECT id, fib(id) FROM t, and function fib is
neither built-in nor user-defined, it will be looked up in the table. If
found, its body will be assumed to hold valid WebAssembly code, compiled
and run.
In order to enable WebAssembly integration, run configure with
./configure --enable-wasm-runtime parameter.
A few examples WebAssembly-based user-defined functions coded in Rust
can be found here: https://github.com/psarna/libsql_bindgen
Here's an inline demo for testing purposes, with a WebAssembly fibonacci
sequence already compiled from Rust and copied in-place:
```
.init_wasm_func_table
CREATE FUNCTION fib LANGUAGE wasm AS '
(module
(type (;0;) (func (param i64) (result i64)))
(func $fib (type 0) (param i64) (result i64)
(local i64)
i64.const 0
local.set 1
block ;; label = @1
local.get 0
i64.const 2
i64.lt_u
br_if 0 (;@1;)
i64.const 0
local.set 1
loop ;; label = @2
local.get 0
i64.const -1
i64.add
call $fib
local.get 1
i64.add
local.set 1
local.get 0
i64.const -2
i64.add
local.tee 0
i64.const 1
i64.gt_u
br_if 0 (;@2;)
end
end
local.get 0
local.get 1
i64.add)
(memory (;0;) 16)
(global $__stack_pointer (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(global (;2;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "fib" (func $fib)))
';
CREATE TABLE IF NOT EXISTS example(id int PRIMARY KEY);
INSERT OR REPLACE INTO example(id) VALUES (7);
INSERT OR REPLACE INTO example(id) VALUES (8);
INSERT OR REPLACE INTO example(id) VALUES (9);
SELECT id, fib(id) FROM example;
```
This series also comes with syntactic sugar for registering and
deregistering Wasm functions dynamically via SQL: CREATE FUNCTION and
DROP FUNCTION: Fixes #18
Fixes #1728 files changed
Lines changed: 8770 additions & 2382 deletions
File tree
- .github/workflows
- doc
- ext/udf
- src
- rust/wasmtime-bindings
- src
- test/rust_suite
- src
- tool
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
69 | 73 | | |
70 | 74 | | |
71 | | - | |
| 75 | + | |
72 | 76 | | |
73 | 77 | | |
74 | 78 | | |
| |||
776 | 780 | | |
777 | 781 | | |
778 | 782 | | |
779 | | - | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
780 | 790 | | |
781 | 791 | | |
782 | 792 | | |
| |||
1318 | 1328 | | |
1319 | 1329 | | |
1320 | 1330 | | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
1321 | 1334 | | |
1322 | 1335 | | |
1323 | 1336 | | |
| |||
0 commit comments