diff --git a/conn.go b/conn.go index 288aa65..f4edd4a 100644 --- a/conn.go +++ b/conn.go @@ -278,7 +278,7 @@ func (c *Conn) SetInterrupt(ctx context.Context) (old context.Context) { break case <-ctx.Done(): // Done was closed. - buf := util.View(c.mod, c.handle+c.api.interrupt, 4) + buf := util.View(c.mod, c.handle+280, 4) (*atomic.Uint32)(unsafe.Pointer(&buf[0])).Store(1) // Wait for the next call to SetInterrupt. <-waiter @@ -294,7 +294,7 @@ func (c *Conn) checkInterrupt() bool { if c.interrupt == nil || c.interrupt.Err() == nil { return false } - buf := util.View(c.mod, c.handle+c.api.interrupt, 4) + buf := util.View(c.mod, c.handle+280, 4) (*atomic.Uint32)(unsafe.Pointer(&buf[0])).Store(1) return true } diff --git a/embed/exports.txt b/embed/exports.txt index ae07974..82974bf 100644 --- a/embed/exports.txt +++ b/embed/exports.txt @@ -44,5 +44,4 @@ sqlite3_backup_init sqlite3_backup_step sqlite3_backup_finish sqlite3_backup_remaining -sqlite3_backup_pagecount -sqlite3_interrupt_offset \ No newline at end of file +sqlite3_backup_pagecount \ No newline at end of file diff --git a/embed/sqlite3.wasm b/embed/sqlite3.wasm index 558de5b..70c9aff 100755 Binary files a/embed/sqlite3.wasm and b/embed/sqlite3.wasm differ diff --git a/internal/vfs/tests/mptest/testdata/main.c b/internal/vfs/tests/mptest/testdata/main.c index a54fe90..a4295c2 100644 --- a/internal/vfs/tests/mptest/testdata/main.c +++ b/internal/vfs/tests/mptest/testdata/main.c @@ -8,18 +8,11 @@ // VFS #include "vfs.c" -sqlite3_destructor_type malloc_destructor = &free; -size_t sqlite3_interrupt_offset = offsetof(sqlite3, u1.isInterrupted); - -int sqlite3_os_init() { - return sqlite3_vfs_register(os_vfs(), /*default=*/true); -} - -__attribute__((constructor)) void premain() { sqlite3_initialize(); } +__attribute__((constructor)) void init() { sqlite3_initialize(); } static int dont_unlink(const char *pathname) { return 0; } #define sqlite3_enable_load_extension(...) #define sqlite3_trace(...) #define unlink dont_unlink #undef UNUSED_PARAMETER -#include "mptest.c" +#include "mptest.c" \ No newline at end of file diff --git a/internal/vfs/tests/mptest/testdata/mptest.wasm b/internal/vfs/tests/mptest/testdata/mptest.wasm index 25ad9c8..1185235 100644 --- a/internal/vfs/tests/mptest/testdata/mptest.wasm +++ b/internal/vfs/tests/mptest/testdata/mptest.wasm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37ceeed293b9f09e9770b40eda3f625447f5a3a74208709886d4411d12f93414 -size 1486113 +oid sha256:aafb873c26d32dbf7498e4c4dd243eb6411c056432818121463d8cb49bc15f70 +size 1479293 diff --git a/internal/vfs/tests/speedtest1/testdata/main.c b/internal/vfs/tests/speedtest1/testdata/main.c index 44b6eee..2998839 100644 --- a/internal/vfs/tests/speedtest1/testdata/main.c +++ b/internal/vfs/tests/speedtest1/testdata/main.c @@ -8,12 +8,5 @@ // VFS #include "vfs.c" -sqlite3_destructor_type malloc_destructor = &free; -size_t sqlite3_interrupt_offset = offsetof(sqlite3, u1.isInterrupted); - -int sqlite3_os_init() { - return sqlite3_vfs_register(os_vfs(), /*default=*/true); -} - #define randomFunc(args...) randomFunc2(args) -#include "speedtest1.c" +#include "speedtest1.c" \ No newline at end of file diff --git a/internal/vfs/tests/speedtest1/testdata/speedtest1.wasm b/internal/vfs/tests/speedtest1/testdata/speedtest1.wasm index 9dc2c98..29060df 100644 --- a/internal/vfs/tests/speedtest1/testdata/speedtest1.wasm +++ b/internal/vfs/tests/speedtest1/testdata/speedtest1.wasm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8167119c344a68217b0301e2e8c288f2e75611d296d7822f841b65911da0275c -size 1520569 +oid sha256:2638f5458f93b60f97006456f60e3e294cffb9ac22b20dba748fbd12e34f056d +size 1515841 diff --git a/internal/vfs/vfs.go b/internal/vfs/vfs.go index e9ac57b..04c5946 100644 --- a/internal/vfs/vfs.go +++ b/internal/vfs/vfs.go @@ -18,6 +18,7 @@ import ( ) func Export(env wazero.HostModuleBuilder) wazero.HostModuleBuilder { + util.RegisterFuncII(env, "go_vfs_find", vfsFind) util.RegisterFuncIIJ(env, "go_localtime", vfsLocaltime) util.RegisterFuncIIII(env, "go_randomness", vfsRandomness) util.RegisterFuncIII(env, "go_sleep", vfsSleep) @@ -62,6 +63,10 @@ func (vfs *vfsState) Close() error { return nil } +func vfsFind(ctx context.Context, mod api.Module, zVfsName uint32) uint32 { + return 0 +} + func vfsLocaltime(ctx context.Context, mod api.Module, pTm uint32, t int64) _ErrorCode { tm := time.Unix(t, 0) var isdst int diff --git a/module.go b/module.go index 7ecc2a8..f3d96a2 100644 --- a/module.go +++ b/module.go @@ -153,7 +153,6 @@ func newModule(mod api.Module) (m *module, err error) { backupFinish: getFun("sqlite3_backup_finish"), backupRemaining: getFun("sqlite3_backup_remaining"), backupPageCount: getFun("sqlite3_backup_pagecount"), - interrupt: getVal("sqlite3_interrupt_offset"), } if err != nil { return nil, err @@ -356,5 +355,4 @@ type sqliteAPI struct { backupRemaining api.Function backupPageCount api.Function destructor uint32 - interrupt uint32 } diff --git a/sqlite3/main.c b/sqlite3/main.c index ef90dfb..756202f 100644 --- a/sqlite3/main.c +++ b/sqlite3/main.c @@ -16,13 +16,6 @@ #include "ext/uuid.c" #include "time.c" -sqlite3_destructor_type malloc_destructor = &free; -size_t sqlite3_interrupt_offset = offsetof(sqlite3, u1.isInterrupted); - -int sqlite3_os_init() { - return sqlite3_vfs_register(os_vfs(), /*default=*/true); -} - __attribute__((constructor)) void init() { sqlite3_initialize(); sqlite3_auto_extension((void (*)(void))sqlite3_base_init); diff --git a/sqlite3/sqlite_cfg.h b/sqlite3/sqlite_cfg.h index 25e0a76..4eac59f 100644 --- a/sqlite3/sqlite_cfg.h +++ b/sqlite3/sqlite_cfg.h @@ -59,9 +59,12 @@ #define SECOND(...) SECOND_I(__VA_ARGS__, , ) #define SECOND_I(A, B, ...) B #define GLUE(A, B) GLUE_I(A, B) -#define GLUE_I(A, B) A##B -#define REPLACE_DEFAULT(a, prefix) SECOND(GLUE(prefix, __LINE__), a) -#define REPLACE_AT_LINE(a) , a +#define GLUE_I(A, B) A##_##B +#define CREATE_REPLACER(A) SECOND(GLUE(A, __LINE__), A) +#define REPLACE_AT_LINE(A) , A // Implemented in vfs.c. -int localtime_s(struct tm *const pTm, time_t const *const pTime); \ No newline at end of file +int localtime_s(struct tm *const pTm, time_t const *const pTime); + +#define sqlite3_vfs_find CREATE_REPLACER(sqlite3_vfs_find_wrapper) +#define sqlite3_vfs_find_wrapper_25397 REPLACE_AT_LINE(sqlite3_vfs_find) \ No newline at end of file diff --git a/sqlite3/vfs.c b/sqlite3/vfs.c index 88ded40..5043f7b 100644 --- a/sqlite3/vfs.c +++ b/sqlite3/vfs.c @@ -3,6 +3,7 @@ #include "sqlite3.h" int go_localtime(struct tm *, sqlite3_int64); +int go_vfs_find(const char *zVfsName); int go_randomness(sqlite3_vfs *, int nByte, char *zOut); int go_sleep(sqlite3_vfs *, int microseconds); @@ -60,9 +61,7 @@ struct go_file { int handle; }; -static_assert(offsetof(struct go_file, handle) == 4, "Unexpected offset"); - -sqlite3_vfs *os_vfs() { +int sqlite3_os_init() { static sqlite3_vfs os_vfs = { .iVersion = 2, .szOsFile = sizeof(struct go_file), @@ -79,9 +78,61 @@ sqlite3_vfs *os_vfs() { .xCurrentTime = go_current_time, .xCurrentTimeInt64 = go_current_time_64, }; - return &os_vfs; + return sqlite3_vfs_register(&os_vfs, /*default=*/true); } +sqlite3_destructor_type malloc_destructor = &free; + int localtime_s(struct tm *const pTm, time_t const *const pTime) { return go_localtime(pTm, (sqlite3_int64)*pTime); } + +#undef sqlite3_vfs_find +sqlite3_vfs *sqlite3_vfs_find_wrapper(const char *zVfsName) { + if (zVfsName) { + static sqlite3_vfs *go_vfs_list; + sqlite3_vfs *found = NULL; + for (sqlite3_vfs **next = &go_vfs_list; *next;) { + sqlite3_vfs *it = *next; + if (go_vfs_find(it->zName)) { + if (!strcmp(zVfsName, it->zName)) found = it; + next = &it->pNext; + } else { + *next = it->pNext; + free(it); + } + } + if (found) { + return found; + } + if (go_vfs_find(zVfsName)) { + sqlite3_vfs *prev = go_vfs_list; + go_vfs_list = malloc(sizeof(sqlite3_vfs) + strlen(zVfsName) + 1); + char *name = (char *)(go_vfs_list + 1); + strcpy(name, zVfsName); + *go_vfs_list = (sqlite3_vfs){ + .iVersion = 2, + .szOsFile = sizeof(struct go_file), + .mxPathname = 512, + .zName = name, + .pNext = prev, + + .xOpen = go_open_wrapper, + .xDelete = go_delete, + .xAccess = go_access, + .xFullPathname = go_full_pathname, + + .xRandomness = go_randomness, + .xSleep = go_sleep, + .xCurrentTime = go_current_time, + .xCurrentTimeInt64 = go_current_time_64, + }; + return go_vfs_list; + } + } + return sqlite3_vfs_find(zVfsName); +} + +static_assert(offsetof(struct go_file, handle) == 4, "Unexpected offset"); +static_assert(offsetof(sqlite3_vfs, zName) == 16, "Unexpected offset"); +static_assert(offsetof(sqlite3, u1.isInterrupted) == 280, "Unexpected offset"); \ No newline at end of file