wazero 1.0.

This commit is contained in:
Nuno Cruces
2023-03-24 21:17:30 +00:00
parent d880d6842c
commit 37a3ff37e8
12 changed files with 34 additions and 66 deletions

View File

@@ -67,18 +67,14 @@ Performance is tested by running
- [x] nested transactions
- [x] incremental BLOB I/O
- [x] online backup
- [ ] snapshots
- [ ] session extension
- [ ] resumable bulk update
- [ ] shared-cache mode
- [ ] unlock-notify
- [ ] custom SQL functions
- [ ] custom VFSes
- [ ] in-memory VFS
- [ ] read-only VFS, wrapping an [`io.ReaderAt`](https://pkg.go.dev/io#ReaderAt)
- [ ] in-memory VFS, wrapping a [`bytes.Buffer`](https://pkg.go.dev/bytes#Buffer)
- [ ] cloud-based VFS, based on [Cloud Backed SQLite](https://sqlite.org/cloudsqlite/doc/trunk/www/index.wiki)
- [ ] custom VFS API
### Alternatives
- [`modernc.org/sqlite`](https://pkg.go.dev/modernc.org/sqlite)

View File

@@ -10,5 +10,6 @@ zig cc --target=wasm32-wasi -flto -g0 -O2 \
-mmutable-globals \
-mbulk-memory -mreference-types \
-mnontrapping-fptoint -msign-ext \
-mexec-model=reactor \
-D_HAVE_SQLITE_CONFIG_H \
$(awk '{print "-Wl,--export="$0}' exports.txt)

Binary file not shown.

2
go.mod
View File

@@ -4,7 +4,7 @@ go 1.19
require (
github.com/ncruces/julianday v0.1.5
github.com/tetratelabs/wazero v1.0.0-rc.2
github.com/tetratelabs/wazero v1.0.0
golang.org/x/sync v0.1.0
golang.org/x/sys v0.6.0
)

4
go.sum
View File

@@ -1,7 +1,7 @@
github.com/ncruces/julianday v0.1.5 h1:hDJ9ejiMp3DHsoZ5KW4c1lwfMjbARS7u/gbYcd0FBZk=
github.com/ncruces/julianday v0.1.5/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
github.com/tetratelabs/wazero v1.0.0-rc.2 h1:OA3UUynnoqxrjCQ94mpAtdO4/oMxFQVNL2BXDMOc66Q=
github.com/tetratelabs/wazero v1.0.0-rc.2/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
github.com/tetratelabs/wazero v1.0.0 h1:sCE9+mjFex95Ki6hdqwvhyF25x5WslADjDKIFU5BXzI=
github.com/tetratelabs/wazero v1.0.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=

View File

@@ -3,14 +3,10 @@ package sqlite3
import (
"context"
"crypto/rand"
"io"
"math"
"os"
"runtime"
"strconv"
"sync"
"sync/atomic"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
@@ -28,11 +24,10 @@ var (
)
var sqlite3 struct {
once sync.Once
runtime wazero.Runtime
compiled wazero.CompiledModule
instances atomic.Uint64
err error
once sync.Once
runtime wazero.Runtime
compiled wazero.CompiledModule
err error
}
func instantiateModule() (*module, error) {
@@ -43,12 +38,7 @@ func instantiateModule() (*module, error) {
return nil, sqlite3.err
}
name := "sqlite3-" + strconv.FormatUint(sqlite3.instances.Add(1), 10)
cfg := wazero.NewModuleConfig().WithName(name).
WithSysWalltime().WithSysNanotime().WithSysNanosleep().
WithOsyield(runtime.Gosched).
WithRandSource(rand.Reader)
cfg := wazero.NewModuleConfig().WithStartFunctions("_initialize")
mod, err := sqlite3.runtime.InstantiateModule(ctx, sqlite3.compiled, cfg)
if err != nil {

View File

@@ -21,10 +21,8 @@ int sqlite3_os_init() {
return sqlite3_vfs_register(os_vfs(), /*default=*/true);
}
int main() {
int rc = sqlite3_initialize();
if (rc != SQLITE_OK) return 1;
__attribute__((constructor)) void premain() {
sqlite3_initialize();
sqlite3_auto_extension((void (*)(void))sqlite3_base_init);
sqlite3_auto_extension((void (*)(void))sqlite3_decimal_init);
sqlite3_auto_extension((void (*)(void))sqlite3_regexp_init);

View File

@@ -2,7 +2,7 @@
#include "sqlite3.h"
int os_localtime(sqlite3_int64, struct tm *);
int os_localtime(struct tm *, sqlite3_int64);
int os_randomness(sqlite3_vfs *, int nByte, char *zOut);
int os_sleep(sqlite3_vfs *, int microseconds);
@@ -140,5 +140,5 @@ sqlite3_vfs *os_vfs() {
}
int localtime_s(struct tm *const pTm, time_t const *const pTime) {
return os_localtime((sqlite3_int64)*pTime, pTm);
return os_localtime(pTm, (sqlite3_int64)*pTime);
}

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eaf30c1ff0cf5acc241c9f7c1ae4c71401ea2be1bd565d67ca913449ef81e542
size 1630832
oid sha256:f81ce390812d944d1fa9b2cc607a3629febab0bc0e4473dad3170134509c1751
size 1630826

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:20619ab46d578da689d08c2e6b1d08b7d4919eb7de20f8220bf3a49014083c87
size 1676135
oid sha256:0e02a26b86832a4703cd2a86c98ff8041d9d889b865a61f324b512a15d2d361e
size 1676129

37
vfs.go
View File

@@ -14,19 +14,11 @@ import (
"github.com/ncruces/julianday"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/sys"
)
func vfsInstantiate(ctx context.Context, r wazero.Runtime) {
wasi := r.NewHostModuleBuilder("wasi_snapshot_preview1")
vfsRegisterFunc(wasi, "proc_exit", vfsExit)
_, err := wasi.Instantiate(ctx)
if err != nil {
panic(err)
}
env := vfsNewEnvModuleBuilder(r)
_, err = env.Instantiate(ctx)
_, err := env.Instantiate(ctx)
if err != nil {
panic(err)
}
@@ -34,7 +26,7 @@ func vfsInstantiate(ctx context.Context, r wazero.Runtime) {
func vfsNewEnvModuleBuilder(r wazero.Runtime) wazero.HostModuleBuilder {
env := r.NewHostModuleBuilder("env")
vfsRegisterFunc(env, "os_localtime", vfsLocaltime)
vfsRegisterFuncT(env, "os_localtime", vfsLocaltime)
vfsRegisterFunc3(env, "os_randomness", vfsRandomness)
vfsRegisterFunc2(env, "os_sleep", vfsSleep)
vfsRegisterFunc2(env, "os_current_time", vfsCurrentTime)
@@ -46,7 +38,7 @@ func vfsNewEnvModuleBuilder(r wazero.Runtime) wazero.HostModuleBuilder {
vfsRegisterFunc1(env, "os_close", vfsClose)
vfsRegisterFuncRW(env, "os_read", vfsRead)
vfsRegisterFuncRW(env, "os_write", vfsWrite)
vfsRegisterFunc(env, "os_truncate", vfsTruncate)
vfsRegisterFuncT(env, "os_truncate", vfsTruncate)
vfsRegisterFunc2(env, "os_sync", vfsSync)
vfsRegisterFunc2(env, "os_file_size", vfsFileSize)
vfsRegisterFunc2(env, "os_lock", vfsLock)
@@ -87,14 +79,7 @@ func (vfs *vfsState) Close() error {
return nil
}
func vfsExit(ctx context.Context, mod api.Module, exitCode uint32) {
// Ensure other callers see the exit code.
_ = mod.CloseWithExitCode(ctx, exitCode)
// Prevent any code from executing after this function.
panic(sys.NewExitError(mod.Name(), exitCode))
}
func vfsLocaltime(ctx context.Context, mod api.Module, t uint64, pTm uint32) uint32 {
func vfsLocaltime(ctx context.Context, mod api.Module, pTm uint32, t uint64) uint32 {
tm := time.Unix(int64(t), 0)
var isdst int
if tm.IsDST() {
@@ -362,10 +347,6 @@ func vfsFileMoved(ctx context.Context, mod api.Module, pFile, pResOut uint32) ui
return _OK
}
func vfsRegisterFunc(mod wazero.HostModuleBuilder, name string, fn any) {
mod.NewFunctionBuilder().WithFunc(fn).Export(name)
}
func vfsRegisterFunc1(mod wazero.HostModuleBuilder, name string, fn func(ctx context.Context, mod api.Module, _ uint32) uint32) {
mod.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(
@@ -425,3 +406,13 @@ func vfsRegisterFuncRW(mod wazero.HostModuleBuilder, name string, fn func(ctx co
[]api.ValueType{api.ValueTypeI32, api.ValueTypeI32, api.ValueTypeI32, api.ValueTypeI64}, []api.ValueType{api.ValueTypeI32}).
Export(name)
}
func vfsRegisterFuncT(mod wazero.HostModuleBuilder, name string, fn func(ctx context.Context, mod api.Module, _ uint32, _ uint64) uint32) {
mod.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(
func(ctx context.Context, mod api.Module, stack []uint64) {
stack[0] = uint64(fn(ctx, mod, uint32(stack[0]), stack[1]))
}),
[]api.ValueType{api.ValueTypeI32, api.ValueTypeI64}, []api.ValueType{api.ValueTypeI32}).
Export(name)
}

View File

@@ -14,19 +14,11 @@ import (
"github.com/ncruces/julianday"
)
func Test_vfsExit(t *testing.T) {
mem := newMemory(128)
ctx := context.TODO()
defer func() { _ = recover() }()
vfsExit(ctx, mem.mod, 1)
t.Error("want panic")
}
func Test_vfsLocaltime(t *testing.T) {
mem := newMemory(128)
ctx := context.TODO()
rc := vfsLocaltime(ctx, mem.mod, 0, 4)
rc := vfsLocaltime(ctx, mem.mod, 4, 0)
if rc != 0 {
t.Fatal("returned", rc)
}