diff --git a/embed/bcw2/bcw2.wasm b/embed/bcw2/bcw2.wasm index d595d67..fedb552 100755 Binary files a/embed/bcw2/bcw2.wasm and b/embed/bcw2/bcw2.wasm differ diff --git a/embed/bcw2/build.sh b/embed/bcw2/build.sh index 6d22c62..3aee93f 100755 --- a/embed/bcw2/build.sh +++ b/embed/bcw2/build.sh @@ -13,11 +13,10 @@ mkdir -p build/ext/ cp "$ROOT"/sqlite3/*.[ch] build/ cp "$ROOT"/sqlite3/*.patch build/ -# https://sqlite.org/src/info/c09656c62155a6e8 -curl -# https://sqlite.org/src/tarball/sqlite.tar.gz?r=c09656c6 | tar xz +# https://sqlite.org/src/info/4196efe83c2fa850 +curl -# https://sqlite.org/src/tarball/sqlite.tar.gz?r=4196efe8 | tar xz cd sqlite -cat ../repro.patch | patch -p0 --no-backup-if-mismatch if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then MSYS_NO_PATHCONV=1 nmake /f makefile.msc sqlite3.c "OPTS=-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES" else diff --git a/embed/bcw2/go.mod b/embed/bcw2/go.mod index 4192b00..ba85c0f 100644 --- a/embed/bcw2/go.mod +++ b/embed/bcw2/go.mod @@ -4,11 +4,11 @@ go 1.23.0 toolchain go1.24.0 -require github.com/ncruces/go-sqlite3 v0.24.0 +require github.com/ncruces/go-sqlite3 v0.25.0 require ( github.com/ncruces/julianday v1.0.0 // indirect github.com/ncruces/sort v0.1.5 // indirect github.com/tetratelabs/wazero v1.9.0 // indirect - golang.org/x/sys v0.30.0 // indirect + golang.org/x/sys v0.32.0 // indirect ) diff --git a/embed/bcw2/go.sum b/embed/bcw2/go.sum index 424fa11..c9e6996 100644 --- a/embed/bcw2/go.sum +++ b/embed/bcw2/go.sum @@ -1,12 +1,12 @@ -github.com/ncruces/go-sqlite3 v0.24.0 h1:Z4jfmzu2NCd4SmyFwLT2OmF3EnTZbqwATvdiuNHNhLA= -github.com/ncruces/go-sqlite3 v0.24.0/go.mod h1:/Vs8ACZHjJ1SA6E9RZUn3EyB1OP3nDQ4z/ar+0fplTQ= +github.com/ncruces/go-sqlite3 v0.25.0 h1:trugKUs98Zwy9KwRr/EUxZHL92LYt7UqcKqAfpGpK+I= +github.com/ncruces/go-sqlite3 v0.25.0/go.mod h1:n6Z7036yFilJx04yV0mi5JWaF66rUmXn1It9Ux8dx68= github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= github.com/ncruces/sort v0.1.5 h1:fiFWXXAqKI8QckPf/6hu/bGFwcEPrirIOFaJqWujs4k= github.com/ncruces/sort v0.1.5/go.mod h1:obJToO4rYr6VWP0Uw5FYymgYGt3Br4RXcs/JdKaXAPk= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= diff --git a/embed/bcw2/repro.patch b/embed/bcw2/repro.patch deleted file mode 100644 index 160dec4..0000000 --- a/embed/bcw2/repro.patch +++ /dev/null @@ -1,23 +0,0 @@ -# https://sqlite.org/src/vpatch?from=67809715977a5bad&to=3f57584710d61174 ---- tool/mkpragmatab.tcl -+++ tool/mkpragmatab.tcl -@@ -526,14 +526,17 @@ - puts $fd [format {#define PragFlg_%-10s 0x%02x /* %s */} \ - $f $fv $flagMeaning($f)] - set fv [expr {$fv*2}] - } - --# Sort the column lists so that longer column lists occur first -+# Sort the column lists so that longer column lists occur first. -+# In the event of a tie, sort column lists lexicographically. - # - proc colscmp {a b} { -- return [expr {[llength $b] - [llength $a]}] -+ set rc [expr {[llength $b] - [llength $a]}] -+ if {$rc} {return $rc} -+ return [string compare $a $b] - } - set cols_list [lsort -command colscmp $cols_list] - - # Generate the array of column names used by pragmas that act like - # queries. diff --git a/embed/exports.txt b/embed/exports.txt index 84d6102..1de4b33 100644 --- a/embed/exports.txt +++ b/embed/exports.txt @@ -66,6 +66,7 @@ sqlite3_errmsg sqlite3_error_offset sqlite3_errstr sqlite3_exec +sqlite3_exec_go sqlite3_expanded_sql sqlite3_file_control sqlite3_filename_database diff --git a/embed/sqlite3.wasm b/embed/sqlite3.wasm index 713fc06..31e1043 100755 Binary files a/embed/sqlite3.wasm and b/embed/sqlite3.wasm differ diff --git a/go.mod b/go.mod index 5d76746..3417b16 100644 --- a/go.mod +++ b/go.mod @@ -8,16 +8,16 @@ require ( github.com/ncruces/julianday v1.0.0 github.com/ncruces/sort v0.1.5 github.com/tetratelabs/wazero v1.9.0 - golang.org/x/crypto v0.36.0 - golang.org/x/sys v0.31.0 + golang.org/x/crypto v0.37.0 + golang.org/x/sys v0.32.0 ) require ( github.com/dchest/siphash v1.2.3 // ext/bloom github.com/google/uuid v1.6.0 // ext/uuid github.com/psanford/httpreadat v0.1.0 // example - golang.org/x/sync v0.12.0 // test - golang.org/x/text v0.23.0 // ext/unicode + golang.org/x/sync v0.13.0 // test + golang.org/x/text v0.24.0 // ext/unicode lukechampine.com/adiantum v1.1.1 // vfs/adiantum ) diff --git a/go.sum b/go.sum index 5fa2242..55dc895 100644 --- a/go.sum +++ b/go.sum @@ -10,13 +10,13 @@ github.com/psanford/httpreadat v0.1.0 h1:VleW1HS2zO7/4c7c7zNl33fO6oYACSagjJIyMIw github.com/psanford/httpreadat v0.1.0/go.mod h1:Zg7P+TlBm3bYbyHTKv/EdtSJZn3qwbPwpfZ/I9GKCRE= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= lukechampine.com/adiantum v1.1.1 h1:4fp6gTxWCqpEbLy40ExiYDDED3oUNWx5cTqBCtPdZqA= lukechampine.com/adiantum v1.1.1/go.mod h1:LrAYVnTYLnUtE/yMp5bQr0HstAf060YUF8nM0B6+rUw= diff --git a/gormlite/go.mod b/gormlite/go.mod index 367c49b..4014629 100644 --- a/gormlite/go.mod +++ b/gormlite/go.mod @@ -5,7 +5,7 @@ go 1.23.0 toolchain go1.24.0 require ( - github.com/ncruces/go-sqlite3 v0.24.0 + github.com/ncruces/go-sqlite3 v0.25.0 gorm.io/gorm v1.25.12 ) @@ -14,6 +14,6 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/ncruces/julianday v1.0.0 // indirect github.com/tetratelabs/wazero v1.9.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect ) diff --git a/gormlite/go.sum b/gormlite/go.sum index 22e2bee..3363b0f 100644 --- a/gormlite/go.sum +++ b/gormlite/go.sum @@ -2,15 +2,15 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/ncruces/go-sqlite3 v0.24.0 h1:Z4jfmzu2NCd4SmyFwLT2OmF3EnTZbqwATvdiuNHNhLA= -github.com/ncruces/go-sqlite3 v0.24.0/go.mod h1:/Vs8ACZHjJ1SA6E9RZUn3EyB1OP3nDQ4z/ar+0fplTQ= +github.com/ncruces/go-sqlite3 v0.25.0 h1:trugKUs98Zwy9KwRr/EUxZHL92LYt7UqcKqAfpGpK+I= +github.com/ncruces/go-sqlite3 v0.25.0/go.mod h1:n6Z7036yFilJx04yV0mi5JWaF66rUmXn1It9Ux8dx68= github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= diff --git a/sqlite3/libc/build.sh b/sqlite3/libc/build.sh index d2a6883..44deede 100755 --- a/sqlite3/libc/build.sh +++ b/sqlite3/libc/build.sh @@ -19,15 +19,17 @@ trap 'rm -f libc.tmp' EXIT -mnontrapping-fptoint -msign-ext \ -fno-stack-protector -fno-stack-clash-protection \ -Wl,--initial-memory=16777216 \ - -Wl,--export=memset \ - -Wl,--export=memcpy \ -Wl,--export=memchr \ -Wl,--export=memcmp \ - -Wl,--export=strlen \ + -Wl,--export=memcpy \ + -Wl,--export=memset \ -Wl,--export=strchr \ + -Wl,--export=strchrnul \ -Wl,--export=strcmp \ + -Wl,--export=strcspn \ + -Wl,--export=strlen \ -Wl,--export=strncmp \ - -Wl,--export=strchrnul + -Wl,--export=strspn "$BINARYEN/wasm-ctor-eval" -g -c _initialize libc.wasm -o libc.tmp "$BINARYEN/wasm-opt" -g --strip --strip-producers -c -O3 \ diff --git a/sqlite3/libc/libc.wasm b/sqlite3/libc/libc.wasm index e0a8d4e..1e4a98c 100755 Binary files a/sqlite3/libc/libc.wasm and b/sqlite3/libc/libc.wasm differ diff --git a/sqlite3/libc/libc.wat b/sqlite3/libc/libc.wat index 4bd601a..a88fc63 100644 --- a/sqlite3/libc/libc.wat +++ b/sqlite3/libc/libc.wat @@ -14,6 +14,8 @@ (export "strncmp" (func $strncmp)) (export "strchrnul" (func $strchrnul)) (export "strchr" (func $strchr)) + (export "strspn" (func $strspn)) + (export "strcspn" (func $strcspn)) (func $memset (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (memory.fill (local.get $0) @@ -226,170 +228,196 @@ (func $strlen (param $0 i32) (result i32) (local $1 i32) (local $2 i32) - (local $scratch i32) - (block $block - (br_if $block - (i32.gt_u - (local.tee $1 - (local.get $0) - ) - (local.tee $2 - (i32.sub - (i32.shl - (memory.size) - (i32.const 16) + (local $3 v128) + (local $scratch v128) + (if + (i32.eqz + (local.tee $2 + (i32.and + (i8x16.bitmask + (i8x16.eq + (v128.load + (local.tee $1 + (i32.and + (local.get $0) + (i32.const -16) + ) + ) + ) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + ) + (i32.shl + (i32.const -1) + (i32.and + (local.get $0) + (i32.const 15) ) - (i32.const 16) ) ) ) ) - (loop $label - (br_if $block - (i32.eqz - (i8x16.all_true - (v128.load align=1 - (local.get $1) + (then + (loop $label + (br_if $label + (i32.eqz + (local.tee $2 + (i8x16.bitmask + (i8x16.eq + (block (result v128) + (local.set $scratch + (v128.load offset=16 + (local.get $1) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 16) + ) + ) + (local.get $scratch) + ) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + ) ) ) ) ) - (br_if $label - (i32.le_u - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 16) - ) - ) - (local.get $2) - ) - ) ) ) - (local.set $0 - (i32.add - (i32.xor - (local.get $0) - (i32.const -1) - ) + (i32.add + (i32.ctz + (local.get $2) + ) + (i32.sub (local.get $1) + (local.get $0) ) ) - (loop $label1 - (local.set $0 - (i32.add - (local.get $0) - (i32.const 1) + ) + (func $strcmp (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 v128) + (local $5 v128) + (local.set $3 + (block $block (result i32) + (if + (i32.and + (i32.or + (local.get $0) + (local.get $1) + ) + (i32.const 15) + ) + (then + (local.set $2 + (i32.load8_u + (local.get $0) + ) + ) + (br $block + (i32.load8_u + (local.get $1) + ) + ) + ) ) - ) - (br_if $label1 - (block (result i32) - (local.set $scratch - (i32.load8_u + (if + (v128.any_true + (v128.xor + (local.tee $5 + (v128.load + (local.get $1) + ) + ) + (local.tee $4 + (v128.load + (local.get $0) + ) + ) + ) + ) + (then + (local.set $2 + (i8x16.extract_lane_u 0 + (local.get $4) + ) + ) + (br $block + (i8x16.extract_lane_u 0 + (local.get $5) + ) + ) + ) + ) + (loop $label + (if + (i32.eqz + (i8x16.all_true + (local.get $4) + ) + ) + (then + (return + (i32.const 0) + ) + ) + ) + (local.set $4 + (v128.load offset=16 + (local.get $0) + ) + ) + (local.set $5 + (v128.load offset=16 (local.get $1) ) ) (local.set $1 (i32.add (local.get $1) - (i32.const 1) - ) - ) - (local.get $scratch) - ) - ) - ) - (local.get $0) - ) - (func $strcmp (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 v128) - (block $block - (br_if $block - (i32.lt_u - (local.tee $2 - (i32.sub - (i32.shl - (memory.size) - (i32.const 16) - ) (i32.const 16) ) ) - (local.get $0) - ) - ) - (br_if $block - (i32.gt_u - (local.get $1) - (local.get $2) - ) - ) - (loop $label - (br_if $block - (v128.any_true - (v128.xor - (v128.load align=1 - (local.get $1) - ) - (local.tee $4 - (v128.load align=1 - (local.get $0) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 16) + ) + ) + (br_if $label + (i32.eqz + (v128.any_true + (v128.xor + (local.get $5) + (local.get $4) ) ) ) ) ) - (if - (i32.eqz - (i8x16.all_true - (local.get $4) - ) - ) - (then - (return - (i32.const 0) - ) + (local.set $2 + (i8x16.extract_lane_u 0 + (local.get $4) ) ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 16) - ) - ) - (br_if $block - (i32.gt_u - (local.tee $0 - (i32.add - (local.get $0) - (i32.const 16) - ) - ) - (local.get $2) - ) - ) - (br_if $label - (i32.le_u - (local.get $1) - (local.get $2) - ) + (i8x16.extract_lane_u 0 + (local.get $5) ) ) ) (if (i32.eq - (local.tee $2 - (i32.load8_u - (local.get $0) - ) + (i32.and + (local.get $2) + (i32.const 255) ) - (local.tee $3 - (i32.load8_u - (local.get $1) - ) + (i32.and + (local.get $3) + (i32.const 255) ) ) (then @@ -405,10 +433,16 @@ (i32.const 1) ) ) + (local.set $2 + (local.get $3) + ) (loop $label1 (if (i32.eqz - (local.get $2) + (i32.and + (local.get $2) + (i32.const 255) + ) ) (then (return @@ -448,8 +482,14 @@ ) ) (i32.sub - (local.get $2) - (local.get $3) + (i32.and + (local.get $2) + (i32.const 255) + ) + (i32.and + (local.get $3) + (i32.const 255) + ) ) ) (func $strncmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) @@ -587,190 +627,528 @@ (local $2 i32) (local $3 v128) (local $4 v128) - (block $block - (br_if $block - (i32.lt_u - (local.tee $2 - (i32.sub - (i32.shl - (memory.size) - (i32.const 16) + (if + (i32.eqz + (local.tee $0 + (i32.and + (i8x16.bitmask + (v128.or + (i8x16.eq + (local.tee $3 + (v128.load + (local.tee $2 + (i32.and + (local.get $0) + (i32.const -16) + ) + ) + ) + ) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (i8x16.eq + (local.get $3) + (local.tee $4 + (i8x16.splat + (local.get $1) + ) + ) + ) ) + ) + (i32.shl + (i32.const -1) + (i32.and + (local.get $0) + (i32.const 15) + ) + ) + ) + ) + ) + (then + (loop $label + (local.set $3 + (v128.load offset=16 + (local.get $2) + ) + ) + (local.set $2 + (i32.add + (local.get $2) (i32.const 16) ) ) - (local.get $0) - ) - ) - (local.set $3 - (i8x16.splat - (local.get $1) - ) - ) - (loop $label - (br_if $block - (i32.eqz - (i8x16.all_true - (local.tee $4 - (v128.load align=1 - (local.get $0) - ) - ) - ) - ) - ) - (br_if $block - (v128.any_true - (i8x16.eq - (local.get $4) - (local.get $3) - ) - ) - ) - (br_if $label - (i32.le_u - (local.tee $0 - (i32.add - (local.get $0) - (i32.const 16) - ) - ) - (local.get $2) - ) - ) - ) - ) - (local.set $1 - (i32.extend8_s - (local.get $1) - ) - ) - (local.set $0 - (i32.sub - (local.get $0) - (i32.const 1) - ) - ) - (loop $label1 - (br_if $label1 - (select - (local.tee $2 - (i32.load8_s + (br_if $label + (i32.eqz (local.tee $0 - (i32.add - (local.get $0) - (i32.const 1) + (i8x16.bitmask + (v128.or + (i8x16.eq + (local.get $3) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (i8x16.eq + (local.get $3) + (local.get $4) + ) + ) ) ) ) ) - (i32.const 0) - (i32.ne - (local.get $1) - (local.get $2) - ) ) ) ) - (local.get $0) + (i32.add + (local.get $2) + (i32.ctz + (local.get $0) + ) + ) ) (func $strchr (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 v128) (local $4 v128) - (block $block - (br_if $block - (i32.lt_u - (local.tee $2 - (i32.sub - (i32.shl - (memory.size) - (i32.const 16) + (if + (i32.eqz + (local.tee $0 + (i32.and + (i8x16.bitmask + (v128.or + (i8x16.eq + (local.tee $3 + (v128.load + (local.tee $2 + (i32.and + (local.get $0) + (i32.const -16) + ) + ) + ) + ) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (i8x16.eq + (local.get $3) + (local.tee $4 + (i8x16.splat + (local.get $1) + ) + ) + ) ) + ) + (i32.shl + (i32.const -1) + (i32.and + (local.get $0) + (i32.const 15) + ) + ) + ) + ) + ) + (then + (loop $label + (local.set $3 + (v128.load offset=16 + (local.get $2) + ) + ) + (local.set $2 + (i32.add + (local.get $2) (i32.const 16) ) ) - (local.get $0) - ) - ) - (local.set $3 - (i8x16.splat - (local.get $1) - ) - ) - (loop $label - (br_if $block - (i32.eqz - (i8x16.all_true - (local.tee $4 - (v128.load align=1 - (local.get $0) - ) - ) - ) - ) - ) - (br_if $block - (v128.any_true - (i8x16.eq - (local.get $4) - (local.get $3) - ) - ) - ) - (br_if $label - (i32.le_u - (local.tee $0 - (i32.add - (local.get $0) - (i32.const 16) - ) - ) - (local.get $2) - ) - ) - ) - ) - (local.set $1 - (i32.extend8_s - (local.get $1) - ) - ) - (local.set $0 - (i32.sub - (local.get $0) - (i32.const 1) - ) - ) - (loop $label1 - (br_if $label1 - (select - (local.tee $2 - (i32.load8_s + (br_if $label + (i32.eqz (local.tee $0 - (i32.add - (local.get $0) - (i32.const 1) + (i8x16.bitmask + (v128.or + (i8x16.eq + (local.get $3) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (i8x16.eq + (local.get $3) + (local.get $4) + ) + ) ) ) ) ) - (i32.const 0) - (i32.ne - (local.get $1) - (local.get $2) - ) ) ) ) (select - (local.get $0) + (local.tee $0 + (i32.add + (local.get $2) + (i32.ctz + (local.get $0) + ) + ) + ) (i32.const 0) (i32.eq + (i32.load8_u + (local.get $0) + ) + (i32.and + (local.get $1) + (i32.const 255) + ) + ) + ) + ) + (func $strspn (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (v128.store + (i32.const 66560) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (v128.store + (i32.const 66544) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (if + (local.tee $2 + (i32.load8_u + (local.get $1) + ) + ) + (then + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (loop $label + (i32.store + (local.tee $3 + (i32.add + (i32.and + (i32.shr_u + (local.get $2) + (i32.const 3) + ) + (i32.const 28) + ) + (i32.const 66544) + ) + ) + (i32.or + (i32.load + (local.get $3) + ) + (i32.shl + (i32.const 1) + (local.get $2) + ) + ) + ) + (local.set $2 + (i32.load8_u + (local.get $1) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (br_if $label + (local.get $2) + ) + ) + ) + ) + (if + (local.tee $2 + (i32.load8_u + (local.tee $1 + (local.get $0) + ) + ) + ) + (then + (loop $label1 + (if + (i32.eqz + (i32.and + (i32.shr_u + (i32.load + (i32.add + (i32.and + (i32.shr_u + (local.get $2) + (i32.const 3) + ) + (i32.const 28) + ) + (i32.const 66544) + ) + ) + (local.get $2) + ) + (i32.const 1) + ) + ) + (then + (return + (i32.sub + (local.get $1) + (local.get $0) + ) + ) + ) + ) + (local.set $2 + (i32.load8_u offset=1 + (local.get $1) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (br_if $label1 + (local.get $2) + ) + ) + ) + ) + (i32.sub + (local.get $1) + (local.get $0) + ) + ) + (func $strcspn (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 v128) + (local $5 v128) + (block $block + (if + (local.tee $2 + (i32.load8_u + (local.get $1) + ) + ) + (then + (br_if $block + (i32.load8_u offset=1 + (local.get $1) + ) + ) + ) + ) + (if + (i32.eqz + (local.tee $2 + (i32.and + (i8x16.bitmask + (v128.or + (i8x16.eq + (local.tee $4 + (v128.load + (local.tee $1 + (i32.and + (local.get $0) + (i32.const -16) + ) + ) + ) + ) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (i8x16.eq + (local.get $4) + (local.tee $5 + (i8x16.splat + (local.get $2) + ) + ) + ) + ) + ) + (i32.shl + (i32.const -1) + (i32.and + (local.get $0) + (i32.const 15) + ) + ) + ) + ) + ) + (then + (loop $label + (local.set $4 + (v128.load offset=16 + (local.get $1) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 16) + ) + ) + (br_if $label + (i32.eqz + (local.tee $2 + (i8x16.bitmask + (v128.or + (i8x16.eq + (local.get $4) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (i8x16.eq + (local.get $4) + (local.get $5) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (return + (i32.sub + (i32.add + (local.get $1) + (i32.ctz + (local.get $2) + ) + ) + (local.get $0) + ) + ) + ) + (v128.store + (i32.const 66560) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (v128.store + (i32.const 66544) + (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ) + (local.set $1 + (i32.add (local.get $1) + (i32.const 1) + ) + ) + (loop $label1 + (i32.store + (local.tee $3 + (i32.add + (i32.and + (i32.shr_u + (local.get $2) + (i32.const 3) + ) + (i32.const 28) + ) + (i32.const 66544) + ) + ) + (i32.or + (i32.load + (local.get $3) + ) + (i32.shl + (i32.const 1) + (local.get $2) + ) + ) + ) + (local.set $2 + (i32.load8_u + (local.get $1) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (br_if $label1 (local.get $2) ) ) + (if + (local.tee $2 + (i32.load8_u + (local.tee $1 + (local.get $0) + ) + ) + ) + (then + (loop $label2 + (if + (i32.and + (i32.shr_u + (i32.load + (i32.add + (i32.and + (i32.shr_u + (local.get $2) + (i32.const 3) + ) + (i32.const 28) + ) + (i32.const 66544) + ) + ) + (local.get $2) + ) + (i32.const 1) + ) + (then + (return + (i32.sub + (local.get $1) + (local.get $0) + ) + ) + ) + ) + (local.set $2 + (i32.load8_u offset=1 + (local.get $1) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (br_if $label2 + (local.get $2) + ) + ) + ) + ) + (i32.sub + (local.get $1) + (local.get $0) + ) ) ;; features section: mutable-globals, nontrapping-float-to-int, simd, bulk-memory, sign-ext, reference-types, multivalue, bulk-memory-opt ) diff --git a/sqlite3/main.c b/sqlite3/main.c index c732937..88da7e7 100644 --- a/sqlite3/main.c +++ b/sqlite3/main.c @@ -1,3 +1,4 @@ +#include "strings.c" // Amalgamation #include "sqlite3.c" // Extensions @@ -10,12 +11,11 @@ #include "ext/spellfix.c" #include "ext/uint.c" // Bindings -#include "bind.c" -#include "column.c" #include "func.c" #include "hooks.c" #include "pointer.c" -#include "result.c" +#include "stmt.c" +#include "text.c" #include "time.c" #include "vfs.c" #include "vtab.c" diff --git a/sqlite3/result.c b/sqlite3/result.c deleted file mode 100644 index b59b26a..0000000 --- a/sqlite3/result.c +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include - -#include "sqlite3.h" - -void sqlite3_result_text_go(sqlite3_context *ctx, const char *zData, - sqlite3_uint64 nData) { - sqlite3_result_text64(ctx, zData, nData, &sqlite3_free, SQLITE_UTF8); -} - -void sqlite3_result_blob_go(sqlite3_context *ctx, const void *zData, - sqlite3_uint64 nData) { - sqlite3_result_blob64(ctx, zData, nData, &sqlite3_free); -} \ No newline at end of file diff --git a/sqlite3/sqlite_opt.h b/sqlite3/sqlite_opt.h index 974efdc..0db37c3 100644 --- a/sqlite3/sqlite_opt.h +++ b/sqlite3/sqlite_opt.h @@ -16,14 +16,12 @@ // #define SQLITE_OMIT_DECLTYPE // #define SQLITE_OMIT_PROGRESS_CALLBACK -// TODO add this: -// #define SQLITE_ENABLE_API_ARMOR - // Other Options #define SQLITE_ALLOW_URI_AUTHORITY #define SQLITE_TRUSTED_SCHEMA 0 #define SQLITE_DEFAULT_FOREIGN_KEYS 1 +#define SQLITE_ENABLE_API_ARMOR #define SQLITE_ENABLE_ATOMIC_WRITE #define SQLITE_ENABLE_BATCH_ATOMIC_WRITE #define SQLITE_ENABLE_COLUMN_METADATA diff --git a/sqlite3/column.c b/sqlite3/stmt.c similarity index 81% rename from sqlite3/column.c rename to sqlite3/stmt.c index 2ff1598..b04a395 100644 --- a/sqlite3/column.c +++ b/sqlite3/stmt.c @@ -2,6 +2,11 @@ #include "sqlite3.h" +int sqlite3_exec_go(sqlite3_stmt *stmt) { + while (sqlite3_step(stmt) == SQLITE_ROW); + return sqlite3_reset(stmt); +} + union sqlite3_data { sqlite3_int64 i; double d; @@ -16,7 +21,7 @@ int sqlite3_columns_go(sqlite3_stmt *stmt, int nCol, char *aType, if (nCol != sqlite3_column_count(stmt)) { return SQLITE_MISUSE; } - int rc = SQLITE_OK; + bool check = false; for (int i = 0; i < nCol; ++i) { const void *ptr = NULL; switch (aType[i] = sqlite3_column_type(stmt, i)) { @@ -36,16 +41,14 @@ int sqlite3_columns_go(sqlite3_stmt *stmt, int nCol, char *aType, ptr = sqlite3_column_blob(stmt, i); break; } - if (ptr == NULL && rc == SQLITE_OK) { - rc = sqlite3_errcode(sqlite3_db_handle(stmt)); - if (rc == SQLITE_ROW || rc == SQLITE_DONE) { - rc = SQLITE_OK; - } - } aData[i].ptr = ptr; aData[i].len = sqlite3_column_bytes(stmt, i); + if (ptr == NULL) check = true; } - return rc; + if (check && SQLITE_NOMEM == sqlite3_errcode(sqlite3_db_handle(stmt))) { + return SQLITE_NOMEM; + } + return SQLITE_OK; } static_assert(offsetof(union sqlite3_data, i) == 0, "Unexpected offset"); diff --git a/sqlite3/strings.c b/sqlite3/strings.c index ea4c2fd..fed7b48 100644 --- a/sqlite3/strings.c +++ b/sqlite3/strings.c @@ -1,5 +1,3 @@ -#include <__macro_PAGESIZE.h> -#include #include #include #include @@ -27,7 +25,7 @@ int memcmp(const void *v1, const void *v2, size_t n) { const v128_t *w2 = v2; for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) { if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) { - break; // *w1 != *w2 + break; } w1++; w2++; @@ -50,7 +48,7 @@ void *memchr(const void *v, int c, size_t n) { const v128_t *w = (void *)v; for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) { if (wasm_v128_any_true(wasm_i8x16_eq(wasm_v128_load(w), wc))) { - break; // *w has a c + break; } w++; } @@ -64,51 +62,41 @@ void *memchr(const void *v, int c, size_t n) { } size_t strlen(const char *s) { - const v128_t *const limit = - (v128_t *)(__builtin_wasm_memory_size(0) * PAGESIZE) - 1; + uintptr_t align = (uintptr_t)s % sizeof(v128_t); + const v128_t *w = (void *)(s - align); - const v128_t *w = (void *)s; - while (w <= limit) { - if (!wasm_i8x16_all_true(wasm_v128_load(w))) { - break; // *w has a NUL + while (true) { + int mask = + wasm_i8x16_bitmask(wasm_i8x16_eq(*w, (v128_t){})) >> align << align; + if (mask) { + return (char *)w - s + __builtin_ctz(mask); } + align = 0; w++; } - - const char *ss = (void *)w; - while (true) { - if (*ss == 0) break; - ss++; - } - return ss - s; } int strcmp(const char *s1, const char *s2) { - const v128_t *const limit = - (v128_t *)(__builtin_wasm_memory_size(0) * PAGESIZE) - 1; - const v128_t *w1 = (void *)s1; const v128_t *w2 = (void *)s2; - while (w1 <= limit && w2 <= limit) { - if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) { - break; // *w1 != *w2 + if (((uintptr_t)s1 | (uintptr_t)s2) % sizeof(v128_t) == 0) { + while (!wasm_v128_any_true(*w1 ^ *w2)) { + if (!wasm_i8x16_all_true(*w1)) { + return 0; + } + w1++; + w2++; } - if (!wasm_i8x16_all_true(wasm_v128_load(w1))) { - return 0; // *w1 == *w2 and have a NUL - } - w1++; - w2++; } const uint8_t *u1 = (void *)w1; const uint8_t *u2 = (void *)w2; while (true) { if (*u1 != *u2) return *u1 - *u2; - if (*u1 == 0) break; + if (*u1 == 0) return 0; u1++; u2++; } - return 0; } int strncmp(const char *s1, const char *s2, size_t n) { @@ -116,10 +104,10 @@ int strncmp(const char *s1, const char *s2, size_t n) { const v128_t *w2 = (void *)s2; for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) { if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) { - break; // *w1 != *w2 + break; } if (!wasm_i8x16_all_true(wasm_v128_load(w1))) { - return 0; // *w1 == *w2 and have a NUL + return 0; } w1++; w2++; @@ -139,27 +127,24 @@ int strncmp(const char *s1, const char *s2, size_t n) { char *strchrnul(const char *s, int c) { c = (char)c; - const v128_t *const limit = - (v128_t *)(__builtin_wasm_memory_size(0) * PAGESIZE) - 1; + if (__builtin_constant_p(c) && c == 0) { + return (char *)s + strlen(s); + } + uintptr_t align = (uintptr_t)s % sizeof(v128_t); + const v128_t *w = (void *)(s - align); const v128_t wc = wasm_i8x16_splat(c); - const v128_t *w = (void *)s; - while (w <= limit) { - if (!wasm_i8x16_all_true(wasm_v128_load(w))) { - break; // *w has a NUL - } - if (wasm_v128_any_true(wasm_i8x16_eq(wasm_v128_load(w), wc))) { - break; // *w has a c + + while (true) { + int mask = wasm_i8x16_bitmask(wasm_i8x16_eq(*w, (v128_t){}) | + wasm_i8x16_eq(*w, wc)) >> + align << align; + if (mask) { + return (char *)w + __builtin_ctz(mask); } + align = 0; w++; } - - s = (void *)w; - while (true) { - if (*s == 0 || *s == c) break; - s++; - } - return (void *)s; } char *strchr(const char *s, int c) { @@ -168,3 +153,29 @@ char *strchr(const char *s, int c) { } #endif + +#define BITOP(a, b, op) \ + ((a)[(b) / (8 * sizeof(size_t))] op((size_t)1) \ + << ((b) % (8 * sizeof(size_t)))) + +size_t strspn(const char *s, const char *c) { + const char *const a = s; + size_t byteset[32 / sizeof(size_t)] = {0}; + + for (; *c && BITOP(byteset, *(uint8_t *)c, |=); c++); + for (; *s && BITOP(byteset, *(uint8_t *)s, &); s++); + return s - a; +} + +size_t strcspn(const char *s, const char *c) { + if (!c[0] || !c[1]) return strchrnul(s, *c) - s; + + const char *const a = s; + size_t byteset[32 / sizeof(size_t)] = {0}; + + for (; *c && BITOP(byteset, *(uint8_t *)c, |=); c++); + for (; *s && !BITOP(byteset, *(uint8_t *)s, &); s++); + return s - a; +} + +#undef BITOP diff --git a/sqlite3/bind.c b/sqlite3/text.c similarity index 53% rename from sqlite3/bind.c rename to sqlite3/text.c index bce1177..0a3ff61 100644 --- a/sqlite3/bind.c +++ b/sqlite3/text.c @@ -10,4 +10,14 @@ int sqlite3_bind_text_go(sqlite3_stmt *stmt, int i, const char *zData, int sqlite3_bind_blob_go(sqlite3_stmt *stmt, int i, const char *zData, sqlite3_uint64 nData) { return sqlite3_bind_blob64(stmt, i, zData, nData, &sqlite3_free); +} + +void sqlite3_result_text_go(sqlite3_context *ctx, const char *zData, + sqlite3_uint64 nData) { + sqlite3_result_text64(ctx, zData, nData, &sqlite3_free, SQLITE_UTF8); +} + +void sqlite3_result_blob_go(sqlite3_context *ctx, const void *zData, + sqlite3_uint64 nData) { + sqlite3_result_blob64(ctx, zData, nData, &sqlite3_free); } \ No newline at end of file diff --git a/stmt.go b/stmt.go index 1870859..7fa2a50 100644 --- a/stmt.go +++ b/stmt.go @@ -110,10 +110,7 @@ func (s *Stmt) Step() bool { s.err = INTERRUPT return false } - return s.step() -} -func (s *Stmt) step() bool { rc := res_t(s.c.call("sqlite3_step", stk_t(s.handle))) switch rc { case _ROW: @@ -141,10 +138,9 @@ func (s *Stmt) Exec() error { if s.c.interrupt.Err() != nil { return INTERRUPT } - // TODO: implement this in C. - for s.step() { - } - return s.Reset() + rc := res_t(s.c.call("sqlite3_exec_go", stk_t(s.handle))) + s.err = nil + return s.c.error(rc) } // Status monitors the performance characteristics of prepared statements. diff --git a/util/sql3util/wasm/build.sh b/util/sql3util/wasm/build.sh index ac587e6..71ad523 100755 --- a/util/sql3util/wasm/build.sh +++ b/util/sql3util/wasm/build.sh @@ -10,7 +10,9 @@ WASI_SDK="$ROOT/tools/wasi-sdk/bin" trap 'rm -f sql3parse_table.tmp' EXIT "$WASI_SDK/clang" --target=wasm32-wasi -std=c23 -g0 -Oz \ - -Wall -Wextra -o sql3parse_table.wasm main.c \ + -Wall -Wextra -Wno-unused-parameter -Wno-unused-function \ + -o sql3parse_table.wasm main.c \ + -I"$ROOT/sqlite3" \ -mexec-model=reactor \ -msimd128 -mmutable-globals -mmultivalue \ -mbulk-memory -mreference-types \ diff --git a/util/sql3util/wasm/main.c b/util/sql3util/wasm/main.c index ede7edb..3f04173 100644 --- a/util/sql3util/wasm/main.c +++ b/util/sql3util/wasm/main.c @@ -1,5 +1,6 @@ #include +#include "strings.c" #include "sql3parse_table.c" static_assert(offsetof(sql3table, name) == 0, "Unexpected offset"); diff --git a/util/sql3util/wasm/sql3parse_table.wasm b/util/sql3util/wasm/sql3parse_table.wasm index 4d3357e..9fe7184 100755 Binary files a/util/sql3util/wasm/sql3parse_table.wasm and b/util/sql3util/wasm/sql3parse_table.wasm differ diff --git a/vfs/tests/mptest/wasm/main.c b/vfs/tests/mptest/wasm/main.c index 57d0ef7..ba70fc9 100644 --- a/vfs/tests/mptest/wasm/main.c +++ b/vfs/tests/mptest/wasm/main.c @@ -3,6 +3,7 @@ // Use the default callback, not the Go one we patched in. #define sqliteBusyCallback sqliteDefaultBusyCallback +#include "strings.c" // Amalgamation #include "sqlite3.c" // VFS diff --git a/vfs/tests/mptest/wasm/mptest.wasm b/vfs/tests/mptest/wasm/mptest.wasm index f47c09b..063d883 100644 Binary files a/vfs/tests/mptest/wasm/mptest.wasm and b/vfs/tests/mptest/wasm/mptest.wasm differ diff --git a/vfs/tests/speedtest1/wasm/main.c b/vfs/tests/speedtest1/wasm/main.c index cc08d56..d191e8e 100644 --- a/vfs/tests/speedtest1/wasm/main.c +++ b/vfs/tests/speedtest1/wasm/main.c @@ -1,6 +1,7 @@ // Use the default callback, not the Go one we patched in. #define sqliteBusyCallback sqliteDefaultBusyCallback +#include "strings.c" // Amalgamation #include "sqlite3.c" // VFS diff --git a/vfs/tests/speedtest1/wasm/speedtest1.wasm b/vfs/tests/speedtest1/wasm/speedtest1.wasm index 87febc9..3d2201f 100644 Binary files a/vfs/tests/speedtest1/wasm/speedtest1.wasm and b/vfs/tests/speedtest1/wasm/speedtest1.wasm differ