mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[experiment] add alternative wasm sqlite3 implementation available via build-tag (#2863)
This allows for building GoToSocial with [SQLite transpiled to WASM](https://github.com/ncruces/go-sqlite3) and accessed through [Wazero](https://wazero.io/).
This commit is contained in:
26
vendor/github.com/tetratelabs/wazero/sys/clock.go
generated
vendored
Normal file
26
vendor/github.com/tetratelabs/wazero/sys/clock.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package sys
|
||||
|
||||
// ClockResolution is a positive granularity of clock precision in
|
||||
// nanoseconds. For example, if the resolution is 1us, this returns 1000.
|
||||
//
|
||||
// Note: Some implementations return arbitrary resolution because there's
|
||||
// no perfect alternative. For example, according to the source in time.go,
|
||||
// windows monotonic resolution can be 15ms. See /RATIONALE.md.
|
||||
type ClockResolution uint32
|
||||
|
||||
// Walltime returns the current unix/epoch time, seconds since midnight UTC
|
||||
// 1 January 1970, with a nanosecond fraction.
|
||||
type Walltime func() (sec int64, nsec int32)
|
||||
|
||||
// Nanotime returns nanoseconds since an arbitrary start point, used to measure
|
||||
// elapsed time. This is sometimes referred to as a tick or monotonic time.
|
||||
//
|
||||
// Note: There are no constraints on the value return except that it
|
||||
// increments. For example, -1 is a valid if the next value is >= 0.
|
||||
type Nanotime func() int64
|
||||
|
||||
// Nanosleep puts the current goroutine to sleep for at least ns nanoseconds.
|
||||
type Nanosleep func(ns int64)
|
||||
|
||||
// Osyield yields the processor, typically to implement spin-wait loops.
|
||||
type Osyield func()
|
83
vendor/github.com/tetratelabs/wazero/sys/error.go
generated
vendored
Normal file
83
vendor/github.com/tetratelabs/wazero/sys/error.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Package sys includes constants and types used by both public and internal APIs.
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// These two special exit codes are reserved by wazero for context Cancel and Timeout integrations.
|
||||
// The assumption here is that well-behaving Wasm programs won't use these two exit codes.
|
||||
const (
|
||||
// ExitCodeContextCanceled corresponds to context.Canceled and returned by ExitError.ExitCode in that case.
|
||||
ExitCodeContextCanceled uint32 = 0xffffffff
|
||||
// ExitCodeDeadlineExceeded corresponds to context.DeadlineExceeded and returned by ExitError.ExitCode in that case.
|
||||
ExitCodeDeadlineExceeded uint32 = 0xefffffff
|
||||
)
|
||||
|
||||
// ExitError is returned to a caller of api.Function when api.Module CloseWithExitCode was invoked,
|
||||
// or context.Context passed to api.Function Call was canceled or reached the Timeout.
|
||||
//
|
||||
// ExitCode zero value means success while any other value is an error.
|
||||
//
|
||||
// Here's an example of how to get the exit code:
|
||||
//
|
||||
// main := module.ExportedFunction("main")
|
||||
// if err := main(ctx); err != nil {
|
||||
// if exitErr, ok := err.(*sys.ExitError); ok {
|
||||
// // This means your module exited with non-zero code!
|
||||
// }
|
||||
// --snip--
|
||||
//
|
||||
// Note: While possible the reason of this was "proc_exit" from "wasi_snapshot_preview1", it could be from other host
|
||||
// functions, for example an AssemblyScript's abort handler, or any arbitrary caller of CloseWithExitCode.
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#proc_exit and
|
||||
// https://www.assemblyscript.org/concepts.html#special-imports
|
||||
//
|
||||
// Note: In the case of context cancellation or timeout, the api.Module from which the api.Function created is closed.
|
||||
type ExitError struct {
|
||||
// Note: this is a struct not a uint32 type as it was originally one and
|
||||
// we don't want to break call-sites that cast into it.
|
||||
exitCode uint32
|
||||
}
|
||||
|
||||
var exitZero = &ExitError{}
|
||||
|
||||
func NewExitError(exitCode uint32) *ExitError {
|
||||
if exitCode == 0 {
|
||||
return exitZero
|
||||
}
|
||||
return &ExitError{exitCode: exitCode}
|
||||
}
|
||||
|
||||
// ExitCode returns zero on success, and an arbitrary value otherwise.
|
||||
func (e *ExitError) ExitCode() uint32 {
|
||||
return e.exitCode
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e *ExitError) Error() string {
|
||||
switch e.exitCode {
|
||||
case ExitCodeContextCanceled:
|
||||
return fmt.Sprintf("module closed with %s", context.Canceled)
|
||||
case ExitCodeDeadlineExceeded:
|
||||
return fmt.Sprintf("module closed with %s", context.DeadlineExceeded)
|
||||
default:
|
||||
return fmt.Sprintf("module closed with exit_code(%d)", e.exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
// Is allows use via errors.Is
|
||||
func (e *ExitError) Is(err error) bool {
|
||||
if target, ok := err.(*ExitError); ok {
|
||||
return e.exitCode == target.exitCode
|
||||
}
|
||||
if e.exitCode == ExitCodeContextCanceled && err == context.Canceled {
|
||||
return true
|
||||
}
|
||||
if e.exitCode == ExitCodeDeadlineExceeded && err == context.DeadlineExceeded {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
107
vendor/github.com/tetratelabs/wazero/sys/stat.go
generated
vendored
Normal file
107
vendor/github.com/tetratelabs/wazero/sys/stat.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
package sys
|
||||
|
||||
import "io/fs"
|
||||
|
||||
// Inode is the file serial number, or zero if unknown.
|
||||
//
|
||||
// Any constant value will invalidate functions that use this for
|
||||
// equivalence, such as os.SameFile (Stat_t.Ino).
|
||||
//
|
||||
// When zero is returned by a `readdir`, some compilers will attempt to
|
||||
// get a non-zero value with `lstat`. Those using this for darwin's definition
|
||||
// of `getdirentries` conflate zero `d_fileno` with a deleted file, so skip the
|
||||
// entry. See /RATIONALE.md for more on this.
|
||||
type Inode = uint64
|
||||
|
||||
// ^-- Inode is a type alias to consolidate documentation and aid in reference
|
||||
// searches. While only Stat_t is exposed publicly at the moment, this is used
|
||||
// internally for Dirent and several function return values.
|
||||
|
||||
// EpochNanos is a timestamp in epoch nanoseconds, or zero if unknown.
|
||||
//
|
||||
// This defines epoch time the same way as Walltime, except this value is
|
||||
// packed into an int64. Common conversions are detailed in the examples.
|
||||
type EpochNanos = int64
|
||||
|
||||
// Stat_t is similar to syscall.Stat_t, except available on all operating
|
||||
// systems, including Windows.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is used for WebAssembly ABI emulating the POSIX `stat` system call.
|
||||
// Fields included are required for WebAssembly ABI including wasip1
|
||||
// (a.k.a. wasix) and wasi-filesystem (a.k.a. wasip2). See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html
|
||||
// - Fields here are required for WebAssembly ABI including wasip1
|
||||
// (a.k.a. wasix) and wasi-filesystem (a.k.a. wasip2).
|
||||
// - This isn't the same as syscall.Stat_t because wazero supports Windows,
|
||||
// which doesn't have that type. runtime.GOOS that has this already also
|
||||
// have inconsistent field lengths, which complicates wasm binding.
|
||||
// - Use NewStat_t to create this from an existing fs.FileInfo.
|
||||
// - For portability, numeric fields are 64-bit when at least one platform
|
||||
// defines it that large.
|
||||
type Stat_t struct {
|
||||
// Dev is the device ID of device containing the file.
|
||||
Dev uint64
|
||||
|
||||
// Ino is the file serial number, or zero if not available. See Inode for
|
||||
// more details including impact returning a zero value.
|
||||
Ino Inode
|
||||
|
||||
// Mode is the same as Mode on fs.FileInfo containing bits to identify the
|
||||
// type of the file (fs.ModeType) and its permissions (fs.ModePerm).
|
||||
Mode fs.FileMode
|
||||
|
||||
// Nlink is the number of hard links to the file.
|
||||
//
|
||||
// Note: This value is platform-specific and often at least one. Linux will
|
||||
// return 1+N for a directory, where BSD (like Darwin) return 2+N, which
|
||||
// includes the dot entry.
|
||||
Nlink uint64
|
||||
|
||||
// Size is the length in bytes for regular files. For symbolic links, this
|
||||
// is length in bytes of the pathname contained in the symbolic link.
|
||||
Size int64
|
||||
|
||||
// Atim is the last data access timestamp in epoch nanoseconds.
|
||||
Atim EpochNanos
|
||||
|
||||
// Mtim is the last data modification timestamp in epoch nanoseconds.
|
||||
Mtim EpochNanos
|
||||
|
||||
// Ctim is the last file status change timestamp in epoch nanoseconds.
|
||||
Ctim EpochNanos
|
||||
}
|
||||
|
||||
// NewStat_t fills a new Stat_t from `info`, including any runtime.GOOS-specific
|
||||
// details from fs.FileInfo `Sys`. When `Sys` is already a *Stat_t, it is
|
||||
// returned as-is.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - When already in fs.FileInfo `Sys`, Stat_t must be a pointer.
|
||||
// - When runtime.GOOS is "windows" Stat_t.Ino will be zero.
|
||||
// - When fs.FileInfo `Sys` is nil or unknown, some fields not in fs.FileInfo
|
||||
// are defaulted: Stat_t.Atim and Stat_t.Ctim are set to `ModTime`, and
|
||||
// are set to ModTime and Stat_t.Nlink is set to 1.
|
||||
func NewStat_t(info fs.FileInfo) Stat_t {
|
||||
// Note: Pointer, not val, for parity with Go, which sets *syscall.Stat_t
|
||||
if st, ok := info.Sys().(*Stat_t); ok {
|
||||
return *st
|
||||
}
|
||||
return statFromFileInfo(info)
|
||||
}
|
||||
|
||||
func defaultStatFromFileInfo(info fs.FileInfo) Stat_t {
|
||||
st := Stat_t{}
|
||||
st.Ino = 0
|
||||
st.Dev = 0
|
||||
st.Mode = info.Mode()
|
||||
st.Nlink = 1
|
||||
st.Size = info.Size()
|
||||
mtim := info.ModTime().UnixNano() // Set all times to the mod time
|
||||
st.Atim = mtim
|
||||
st.Mtim = mtim
|
||||
st.Ctim = mtim
|
||||
return st
|
||||
}
|
29
vendor/github.com/tetratelabs/wazero/sys/stat_bsd.go
generated
vendored
Normal file
29
vendor/github.com/tetratelabs/wazero/sys/stat_bsd.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
//go:build (amd64 || arm64) && (darwin || freebsd)
|
||||
|
||||
package sys
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const sysParseable = true
|
||||
|
||||
func statFromFileInfo(info fs.FileInfo) Stat_t {
|
||||
if d, ok := info.Sys().(*syscall.Stat_t); ok {
|
||||
st := Stat_t{}
|
||||
st.Dev = uint64(d.Dev)
|
||||
st.Ino = d.Ino
|
||||
st.Mode = info.Mode()
|
||||
st.Nlink = uint64(d.Nlink)
|
||||
st.Size = d.Size
|
||||
atime := d.Atimespec
|
||||
st.Atim = atime.Sec*1e9 + atime.Nsec
|
||||
mtime := d.Mtimespec
|
||||
st.Mtim = mtime.Sec*1e9 + mtime.Nsec
|
||||
ctime := d.Ctimespec
|
||||
st.Ctim = ctime.Sec*1e9 + ctime.Nsec
|
||||
return st
|
||||
}
|
||||
return defaultStatFromFileInfo(info)
|
||||
}
|
32
vendor/github.com/tetratelabs/wazero/sys/stat_linux.go
generated
vendored
Normal file
32
vendor/github.com/tetratelabs/wazero/sys/stat_linux.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
//go:build (amd64 || arm64 || riscv64) && linux
|
||||
|
||||
// Note: This expression is not the same as compiler support, even if it looks
|
||||
// similar. Platform functions here are used in interpreter mode as well.
|
||||
|
||||
package sys
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const sysParseable = true
|
||||
|
||||
func statFromFileInfo(info fs.FileInfo) Stat_t {
|
||||
if d, ok := info.Sys().(*syscall.Stat_t); ok {
|
||||
st := Stat_t{}
|
||||
st.Dev = uint64(d.Dev)
|
||||
st.Ino = uint64(d.Ino)
|
||||
st.Mode = info.Mode()
|
||||
st.Nlink = uint64(d.Nlink)
|
||||
st.Size = d.Size
|
||||
atime := d.Atim
|
||||
st.Atim = atime.Sec*1e9 + atime.Nsec
|
||||
mtime := d.Mtim
|
||||
st.Mtim = mtime.Sec*1e9 + mtime.Nsec
|
||||
ctime := d.Ctim
|
||||
st.Ctim = ctime.Sec*1e9 + ctime.Nsec
|
||||
return st
|
||||
}
|
||||
return defaultStatFromFileInfo(info)
|
||||
}
|
17
vendor/github.com/tetratelabs/wazero/sys/stat_unsupported.go
generated
vendored
Normal file
17
vendor/github.com/tetratelabs/wazero/sys/stat_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
//go:build (!((amd64 || arm64 || riscv64) && linux) && !((amd64 || arm64) && (darwin || freebsd)) && !((amd64 || arm64) && windows)) || js
|
||||
|
||||
package sys
|
||||
|
||||
import "io/fs"
|
||||
|
||||
// sysParseable is only used here as we define "supported" as being able to
|
||||
// parse `info.Sys()`. The above `go:build` constraints exclude 32-bit until
|
||||
// that's requested.
|
||||
//
|
||||
// TODO: When Go 1.21 is out, use the "unix" build constraint (as 1.21 makes
|
||||
// our floor Go version 1.19.
|
||||
const sysParseable = false
|
||||
|
||||
func statFromFileInfo(info fs.FileInfo) Stat_t {
|
||||
return defaultStatFromFileInfo(info)
|
||||
}
|
26
vendor/github.com/tetratelabs/wazero/sys/stat_windows.go
generated
vendored
Normal file
26
vendor/github.com/tetratelabs/wazero/sys/stat_windows.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
//go:build (amd64 || arm64) && windows
|
||||
|
||||
package sys
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const sysParseable = true
|
||||
|
||||
func statFromFileInfo(info fs.FileInfo) Stat_t {
|
||||
if d, ok := info.Sys().(*syscall.Win32FileAttributeData); ok {
|
||||
st := Stat_t{}
|
||||
st.Ino = 0 // not in Win32FileAttributeData
|
||||
st.Dev = 0 // not in Win32FileAttributeData
|
||||
st.Mode = info.Mode()
|
||||
st.Nlink = 1 // not in Win32FileAttributeData
|
||||
st.Size = info.Size()
|
||||
st.Atim = d.LastAccessTime.Nanoseconds()
|
||||
st.Mtim = d.LastWriteTime.Nanoseconds()
|
||||
st.Ctim = d.CreationTime.Nanoseconds()
|
||||
return st
|
||||
}
|
||||
return defaultStatFromFileInfo(info)
|
||||
}
|
Reference in New Issue
Block a user