mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
wazero 1.0.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
2
go.mod
@@ -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
4
go.sum
@@ -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=
|
||||
|
||||
20
module.go
20
module.go
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
4
tests/mptest/testdata/mptest.wasm
vendored
4
tests/mptest/testdata/mptest.wasm
vendored
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:eaf30c1ff0cf5acc241c9f7c1ae4c71401ea2be1bd565d67ca913449ef81e542
|
||||
size 1630832
|
||||
oid sha256:f81ce390812d944d1fa9b2cc607a3629febab0bc0e4473dad3170134509c1751
|
||||
size 1630826
|
||||
|
||||
4
tests/speedtest1/testdata/speedtest1.wasm
vendored
4
tests/speedtest1/testdata/speedtest1.wasm
vendored
@@ -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
37
vfs.go
@@ -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)
|
||||
}
|
||||
|
||||
10
vfs_test.go
10
vfs_test.go
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user