Localtime.

This commit is contained in:
Nuno Cruces
2023-01-24 11:17:30 -08:00
parent 97227017a7
commit dbfddf2c5b
6 changed files with 76 additions and 24 deletions

View File

@@ -40,7 +40,7 @@ func OpenFlags(filename string, flags OpenFlag) (conn *Conn, err error) {
c := newConn(module)
c.ctx = context.Background()
namePtr := c.newString(filename)
connPtr := c.new(ptrSize)
connPtr := c.new(wordSize)
defer c.free(namePtr)
defer c.free(connPtr)
@@ -86,8 +86,8 @@ func (c *Conn) Prepare(sql string) (stmt *Stmt, tail string, err error) {
func (c *Conn) PrepareFlags(sql string, flags PrepareFlag) (stmt *Stmt, tail string, err error) {
sqlPtr := c.newString(sql)
stmtPtr := c.new(ptrSize)
tailPtr := c.new(ptrSize)
stmtPtr := c.new(wordSize)
tailPtr := c.new(wordSize)
defer c.free(sqlPtr)
defer c.free(stmtPtr)
defer c.free(tailPtr)
@@ -218,4 +218,4 @@ func getString(memory api.Memory, ptr, maxlen uint32) string {
}
}
const ptrSize = 4
const wordSize = 4

View File

@@ -12,22 +12,7 @@ zig cc --target=wasm32-wasi -flto -g0 -O2 \
-mmutable-globals \
-mbulk-memory -mreference-types \
-mnontrapping-fptoint -msign-ext \
-DSQLITE_OS_OTHER=1 -DSQLITE_BYTEORDER=1234 \
-DHAVE_ISNAN -DHAVE_USLEEP -DHAVE_MALLOC_USABLE_SIZE \
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_LOCKING_MODE=1 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_AUTOINIT \
-DSQLITE_OMIT_UTF16 \
-DSQLITE_USE_ALLOCA \
-D_HAVE_SQLITE_CONFIG_H \
-Wl,--export=malloc \
-Wl,--export=free \
-Wl,--export=malloc_destructor \

View File

@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <time.h>
#include "sqlite3.h"
@@ -7,6 +8,8 @@ int main() {
if (rc != SQLITE_OK) return 1;
}
int go_localtime(sqlite3_int64, struct tm *);
int go_randomness(sqlite3_vfs *, int nByte, char *zOut);
int go_sleep(sqlite3_vfs *, int microseconds);
int go_current_time(sqlite3_vfs *, double *);
@@ -48,6 +51,10 @@ static int no_file_control(sqlite3_file *pFile, int op, void *pArg) {
static int no_sector_size(sqlite3_file *pFile) { return 0; }
static int no_device_characteristics(sqlite3_file *pFile) { return 0; }
int localtime_s(struct tm *const pTm, time_t const *const pTime) {
return go_localtime((sqlite3_int64)*pTime, pTm);
}
static int go_open_c(sqlite3_vfs *vfs, sqlite3_filename zName,
sqlite3_file *file, int flags, int *pOutFlags) {
static const sqlite3_io_methods go_io = {

36
sqlite3/sqlite_cfg.h Normal file
View File

@@ -0,0 +1,36 @@
#include <time.h>
// Platform Configuration
#define SQLITE_OS_OTHER 1
#define SQLITE_BYTEORDER 1234
#define HAVE_ISNAN 1
#define HAVE_USLEEP 1
#define HAVE_LOCALTIME_S 1
#define HAVE_MALLOC_USABLE_SIZE 1
// Recommended Options
#define SQLITE_DQS 0
#define SQLITE_THREADSAFE 0
#define SQLITE_DEFAULT_MEMSTATUS 0
#define SQLITE_DEFAULT_WAL_SYNCHRONOUS 1
#define SQLITE_LIKE_DOESNT_MATCH_BLOBS
#define SQLITE_MAX_EXPR_DEPTH 0
#define SQLITE_OMIT_DECLTYPE
#define SQLITE_OMIT_DEPRECATED
#define SQLITE_OMIT_PROGRESS_CALLBACK
#define SQLITE_OMIT_SHARED_CACHE
#define SQLITE_OMIT_AUTOINIT
#define SQLITE_USE_ALLOCA
// Need this to access WAL databases without the use of shared memory.
#define SQLITE_DEFAULT_LOCKING_MODE 1
// Go uses UTF-8 everywhere.
#define SQLITE_OMIT_UTF16
// Remove some testing code.
#define SQLITE_UNTESTABLE
// Implemented in Go.
int localtime_s(struct tm *const pTm, time_t const *const pTime);

24
vfs.go
View File

@@ -26,6 +26,7 @@ func vfsInstantiate(ctx context.Context, r wazero.Runtime) (err error) {
}
env := r.NewHostModuleBuilder("env")
env.NewFunctionBuilder().WithFunc(vfsLocaltime).Export("go_localtime")
env.NewFunctionBuilder().WithFunc(vfsRandomness).Export("go_randomness")
env.NewFunctionBuilder().WithFunc(vfsSleep).Export("go_sleep")
env.NewFunctionBuilder().WithFunc(vfsCurrentTime).Export("go_current_time")
@@ -54,6 +55,29 @@ func vfsExit(ctx context.Context, mod api.Module, exitCode uint32) {
panic(sys.NewExitError(mod.Name(), exitCode))
}
func vfsLocaltime(ctx context.Context, mod api.Module, t uint64, pTm uint32) uint32 {
tm := time.Unix(int64(t), 0)
var isdst int
if tm.IsDST() {
isdst = 1
}
// https://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
if mem := mod.Memory(); true &&
mem.WriteUint32Le(pTm+0*wordSize, uint32(tm.Second())) &&
mem.WriteUint32Le(pTm+1*wordSize, uint32(tm.Minute())) &&
mem.WriteUint32Le(pTm+2*wordSize, uint32(tm.Hour())) &&
mem.WriteUint32Le(pTm+3*wordSize, uint32(tm.Day())) &&
mem.WriteUint32Le(pTm+4*wordSize, uint32(tm.Month()-time.January)) &&
mem.WriteUint32Le(pTm+5*wordSize, uint32(tm.Year()-1900)) &&
mem.WriteUint32Le(pTm+6*wordSize, uint32(tm.Weekday()-time.Sunday)) &&
mem.WriteUint32Le(pTm+7*wordSize, uint32(tm.YearDay()-1)) &&
mem.WriteUint32Le(pTm+8*wordSize, uint32(isdst)) {
return _OK
}
panic(rangeErr)
}
func vfsRandomness(ctx context.Context, mod api.Module, pVfs, nByte, zByte uint32) uint32 {
mem, ok := mod.Memory().Read(zByte, nByte)
if !ok {

View File

@@ -92,7 +92,7 @@ func (p vfsFilePtr) OSFile() *os.File {
}
func (p vfsFilePtr) ID() uint32 {
id, ok := p.Memory().ReadUint32Le(p.ptr + ptrSize)
id, ok := p.Memory().ReadUint32Le(p.ptr + wordSize)
if !ok {
panic(rangeErr)
}
@@ -100,7 +100,7 @@ func (p vfsFilePtr) ID() uint32 {
}
func (p vfsFilePtr) Lock() uint32 {
lk, ok := p.Memory().ReadUint32Le(p.ptr + 2*ptrSize)
lk, ok := p.Memory().ReadUint32Le(p.ptr + 2*wordSize)
if !ok {
panic(rangeErr)
}
@@ -108,14 +108,14 @@ func (p vfsFilePtr) Lock() uint32 {
}
func (p vfsFilePtr) SetID(id uint32) vfsFilePtr {
if ok := p.Memory().WriteUint32Le(p.ptr+ptrSize, id); !ok {
if ok := p.Memory().WriteUint32Le(p.ptr+wordSize, id); !ok {
panic(rangeErr)
}
return p
}
func (p vfsFilePtr) SetLock(lock uint32) vfsFilePtr {
if ok := p.Memory().WriteUint32Le(p.ptr+2*ptrSize, lock); !ok {
if ok := p.Memory().WriteUint32Le(p.ptr+2*wordSize, lock); !ok {
panic(rangeErr)
}
return p