1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-10-24 09:53:10 +03:00

Diverse cleanups and docs in the JS and kvvfs pieces. Functional changes: (A) ensure that the 'i32' JS/WASM func arg/result conversion works properly with a 64-bit-memory WASM build (which we neither use nor test but [https://webassembly.org/news/2025-09-17-wasm-3.0/ | the newly-ratified WASM 3.0] brings within potential reach). (B) Fix sqlite3_js_posix_create_file() to not deallocate its input array if the client passes in raw memory (the library has never used it that way but the API permits it).

FossilOrigin-Name: 79af65a694fbbb3d501fb2ebd835c259ca644e0dafdd71eeb9f0a7c0e9128a1e
This commit is contained in:
stephan
2025-09-19 17:24:47 +00:00
parent 194d6edeb6
commit d4cc844a2b
9 changed files with 171 additions and 141 deletions

View File

@@ -243,21 +243,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
purpose. For example: purpose. For example:
const pAuxDtor = wasm.installFunction('v(p)', function(ptr){ const pAuxDtor = wasm.installFunction('v(p)', function(ptr){
//free ptr //free ptr
}); });
myDb.onclose = { myDb.onclose = {
after: ()=>{ after: ()=>{
wasm.uninstallFunction(pAuxDtor); wasm.uninstallFunction(pAuxDtor);
} }
}; };
Then pass pAuxDtor as the final argument to appropriate Then pass pAuxDtor as the final argument to appropriate
sqlite3_set_auxdata() calls. sqlite3_set_auxdata() calls.
Note that versions prior to 3.49.0 ostensibly had automatic Prior to 3.49.0 this binding ostensibly had automatic
function conversion here but a typo prevented it from function conversion here but a typo prevented it from
working. Rather than fix it, it was removed because testing the working. Rather than fix it, it was removed because testing
fix brought the huge potential for memory leaks to the the fix brought the huge potential for memory leaks to the
forefront. forefront.
*/ */
["sqlite3_set_auxdata", undefined, [ ["sqlite3_set_auxdata", undefined, [
@@ -323,7 +323,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"], ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"] ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
/* This list gets extended below */ /* This list gets extended with optional pieces below */
]/*.core*/, ]/*.core*/,
/** /**
Functions which require BigInt (int64) support are separated Functions which require BigInt (int64) support are separated
@@ -375,7 +375,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
]], ]],
["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]], ["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]],
["sqlite3_value_int64","i64", "sqlite3_value*"] ["sqlite3_value_int64","i64", "sqlite3_value*"]
/* This list gets extended below */ /* This list gets extended with optional pieces below */
]/*.int64*/, ]/*.int64*/,
/** /**
Functions which are intended solely for API-internal use by the Functions which are intended solely for API-internal use by the
@@ -435,12 +435,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
name: "sqlite3_set_authorizer::xAuth", name: "sqlite3_set_authorizer::xAuth",
signature: "i(pi"+"ssss)", signature: "i(pi"+"ssss)",
contextKey: (argv, argIndex)=>argv[0/*(sqlite3*)*/], contextKey: (argv, argIndex)=>argv[0/*(sqlite3*)*/],
/**
We use callProxy here to ensure (A) that exceptions
thrown from callback() have well-defined behavior and (B)
that its result is coerced to an integer.
*/
callProxy: (callback)=>{ callProxy: (callback)=>{
return (pV, iCode, s0, s1, s2, s3)=>{ return (pV, iCode, s0, s1, s2, s3)=>{
try{ try{
s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1); s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1);
s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3); s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3);
return callback(pV, iCode, s0, s1, s2, s3) || 0; return callback(pV, iCode, s0, s1, s2, s3) | 0;
}catch(e){ }catch(e){
return e.resultCode || capi.SQLITE_ERROR; return e.resultCode || capi.SQLITE_ERROR;
} }
@@ -470,12 +475,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
//#if enable-see //#if enable-see
if( !!wasm.exports.sqlite3_key_v2 ){ if( !!wasm.exports.sqlite3_key_v2 ){
/** /**
This code is capable of using an SEE build but note that an SEE This code is capable of using an SEE build but an SEE WASM
WASM build is generally incompatible with SEE's license build is generally incompatible with SEE's license conditions.
conditions. It is permitted for use internally in organizations The project's official stance on WASM builds of SEE is: it is
which have licensed SEE, but not for public sites because permitted for use internally within organizations which have
exposing an SEE build of sqlite3.wasm effectively provides all licensed SEE, but not for public sites because exposing an SEE
clients with a working copy of the commercial SEE code. build of sqlite3.wasm effectively provides all clients with a
working copy of SEE.
*/ */
bindingSignatures.core.push( bindingSignatures.core.push(
["sqlite3_key", "int", "sqlite3*", "string", "int"], ["sqlite3_key", "int", "sqlite3*", "string", "int"],
@@ -496,12 +502,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]], ["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]],
["sqlite3_drop_modules", "int", ["sqlite3*", "**"]], ["sqlite3_drop_modules", "int", ["sqlite3*", "**"]],
["sqlite3_vtab_collation","string","sqlite3_index_info*","int"], ["sqlite3_vtab_collation","string","sqlite3_index_info*","int"],
/*["sqlite3_vtab_config" is variadic and requires a hand-written
proxy.] */
["sqlite3_vtab_distinct","int", "sqlite3_index_info*"], ["sqlite3_vtab_distinct","int", "sqlite3_index_info*"],
["sqlite3_vtab_in","int", "sqlite3_index_info*", "int", "int"], ["sqlite3_vtab_in","int", "sqlite3_index_info*", "int", "int"],
["sqlite3_vtab_in_first", "int", "sqlite3_value*", "**"], ["sqlite3_vtab_in_first", "int", "sqlite3_value*", "**"],
["sqlite3_vtab_in_next", "int", "sqlite3_value*", "**"], ["sqlite3_vtab_in_next", "int", "sqlite3_value*", "**"],
/*["sqlite3_vtab_config" is variadic and requires a hand-written
proxy.] */
["sqlite3_vtab_nochange","int", "sqlite3_context*"], ["sqlite3_vtab_nochange","int", "sqlite3_context*"],
["sqlite3_vtab_on_conflict","int", "sqlite3*"], ["sqlite3_vtab_on_conflict","int", "sqlite3*"],
["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"] ["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"]
@@ -713,7 +719,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*session/changeset APIs*/ }/*session/changeset APIs*/
/** /**
Install JS<->C struct bindings for the non-opaque struct types we Prepare JS<->C struct bindings for the non-opaque struct types we
need... need...
*/ */
sqlite3.StructBinder = globalThis.Jaccwabyt({ sqlite3.StructBinder = globalThis.Jaccwabyt({
@@ -722,7 +728,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
dealloc: wasm.dealloc, dealloc: wasm.dealloc,
bigIntEnabled: wasm.bigIntEnabled, bigIntEnabled: wasm.bigIntEnabled,
memberPrefix: /* Never change this: this prefix is baked into any memberPrefix: /* Never change this: this prefix is baked into any
amount of code and client-facing docs. */ '$' amount of code and client-facing docs. (Much
later: it probably should have been '$$', but see
the previous sentence.) */ '$'
}); });
delete globalThis.Jaccwabyt; delete globalThis.Jaccwabyt;
@@ -745,16 +753,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
- Anything else: gets coerced to a JS string for use as a map - Anything else: gets coerced to a JS string for use as a map
key. If a matching entry is found (as described next), it is key. If a matching entry is found (as described next), it is
returned, else wasm.allocCString() is used to create a a new returned, else wasm.allocCString() is used to create a a new
string, map its pointer to (''+v) for the remainder of the string, map its pointer to a copy of (''+v) for the remainder
application's life, and returns that pointer value for this of the application's life, and returns that pointer value for
call and all future calls which are passed a this call and all future calls which are passed a
string-equivalent argument. string-equivalent argument.
Use case: sqlite3_bind_pointer() and sqlite3_result_pointer() Use case: sqlite3_bind_pointer(), sqlite3_result_pointer(), and
call for "a static string and preferably a string sqlite3_value_pointer() call for "a static string and
literal." This converter is used to ensure that the string preferably a string literal". This converter is used to ensure
value seen by those functions is long-lived and behaves as they that the string value seen by those functions is long-lived and
need it to. behaves as they need it to, at the cost of a one-time leak of
each distinct key.
*/ */
wasm.xWrap.argAdapter( wasm.xWrap.argAdapter(
'string:static', 'string:static',
@@ -822,6 +831,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
); );
} }
/**
Alias `T*` to `*` for return type conversions for common T
types, primarily to improve legibility of their binding
signatures.
*/
const __xRcPtr = wasm.xWrap.resultAdapter('*'); const __xRcPtr = wasm.xWrap.resultAdapter('*');
wasm.xWrap.resultAdapter('sqlite3*', __xRcPtr) wasm.xWrap.resultAdapter('sqlite3*', __xRcPtr)
('sqlite3_context*', __xRcPtr) ('sqlite3_context*', __xRcPtr)
@@ -834,15 +848,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
Populate api object with sqlite3_...() by binding the "raw" wasm Populate api object with sqlite3_...() by binding the "raw" wasm
exports into type-converting proxies using wasm.xWrap(). exports into type-converting proxies using wasm.xWrap().
*/ */
if(0 === wasm.exports.sqlite3_step.length){
/* This environment wraps exports in nullary functions, which means
we must disable the arg-count validation we otherwise perform
on the wrappers. */
wasm.xWrap.doArgcCheck = false;
sqlite3.config.warn(
"Disabling sqlite3.wasm.xWrap.doArgcCheck due to environmental quirks."
);
}
for(const e of bindingSignatures.core){ for(const e of bindingSignatures.core){
capi[e[0]] = wasm.xWrap.apply(null, e); capi[e[0]] = wasm.xWrap.apply(null, e);
} }
@@ -854,18 +859,16 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
wasm.bigIntEnabled is true, install a bogus impl which throws wasm.bigIntEnabled is true, install a bogus impl which throws
if called when bigIntEnabled is false. The alternative would be if called when bigIntEnabled is false. The alternative would be
to elide these functions altogether, which seems likely to to elide these functions altogether, which seems likely to
cause more confusion. */ cause more confusion, as documented APIs would resolve to the
const fI64Disabled = function(fname){ undefined value in incompatible builds. */
return ()=>toss(fname+"() is unavailable due to lack",
"of BigInt support in this build.");
};
for(const e of bindingSignatures.int64){ for(const e of bindingSignatures.int64){
capi[e[0]] = wasm.bigIntEnabled capi[e[0]] = wasm.bigIntEnabled
? wasm.xWrap.apply(null, e) ? wasm.xWrap.apply(null, e)
: fI64Disabled(e[0]); : ()=>toss(e[0]+"() is unavailable due to lack",
"of BigInt support in this build.");
} }
/* We don't need these anymore... */ /* We're done with bindingSignatures but it's const, so... */
delete bindingSignatures.core; delete bindingSignatures.core;
delete bindingSignatures.int64; delete bindingSignatures.int64;
delete bindingSignatures.wasmInternal; delete bindingSignatures.wasmInternal;
@@ -949,6 +952,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
string, or undefined if no such mapping is found. string, or undefined if no such mapping is found.
*/ */
capi.sqlite3_js_rc_str = (rc)=>__rcMap[rc]; capi.sqlite3_js_rc_str = (rc)=>__rcMap[rc];
/* Bind all registered C-side structs... */ /* Bind all registered C-side structs... */
const notThese = Object.assign(Object.create(null),{ const notThese = Object.assign(Object.create(null),{
// For each struct to NOT register, map its name to true: // For each struct to NOT register, map its name to true:
@@ -968,7 +972,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
} }
if(capi.sqlite3_index_info){ if(capi.sqlite3_index_info){
/* Move these inner structs into sqlite3_index_info. Binding /* Move these inner structs into sqlite3_index_info. Binding
** them to WASM requires that we create global-scope structs to ** them to WASM requires that we create top-level structs to
** model them with, but those are no longer needed after we've ** model them with, but those are no longer needed after we've
** passed them to StructBinder. */ ** passed them to StructBinder. */
for(const k of ['sqlite3_index_constraint', for(const k of ['sqlite3_index_constraint',

View File

@@ -747,12 +747,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
closed when onclose.after is called. If this db is not opened closed when onclose.after is called. If this db is not opened
when close() is called, neither of the handlers are called. Any when close() is called, neither of the handlers are called. Any
exceptions the handlers throw are ignored because "destructors exceptions the handlers throw are ignored because "destructors
must not throw." must not throw".
Note that garbage collection of a db handle, if it happens at Garbage collection of a db handle, if it happens at all, will
all, will never trigger close(), so onclose handlers are not a never trigger close(), so onclose handlers are not a reliable
reliable way to implement close-time cleanup or maintenance of way to implement close-time cleanup or maintenance of a db.
a db.
If this instance was created using DB.wrapHandle() and does not If this instance was created using DB.wrapHandle() and does not
own this.pointer then it does not close the db handle but it own this.pointer then it does not close the db handle but it

View File

@@ -1046,10 +1046,16 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
}/*compileOptionUsed()*/; }/*compileOptionUsed()*/;
/** /**
sqlite3.wasm.pstack (pseudo-stack) holds a special-case sqlite3.wasm.pstack (pseudo-stack) holds a special-case intended
stack-style allocator intended only for use with _small_ data of solely for short-lived, small data. In practice, it's primarily
not more than (in total) a few kb in size, managed as if it were used to allocate output pointers. It mus not be used for any
stack-based. memory which needs to outlive the scope in which it's obtained
from pstack.
The library guarantees only that a minimum of 2kb are available
in this allocator, and it may provide more (it's a build-time
value). pstack.quota and pstack.remaining can be used to get the
total resp. remaining amount of memory.
It has only a single intended usage: It has only a single intended usage:
@@ -1081,6 +1087,9 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
Sets the current pstack position to the given pointer. Results Sets the current pstack position to the given pointer. Results
are undefined if the passed-in value did not come from are undefined if the passed-in value did not come from
this.pointer. this.pointer.
In debug builds this may trigger an assert() in the WASM
environment if passed an illegal value.
*/ */
restore: wasm.exports.sqlite3__wasm_pstack_restore, restore: wasm.exports.sqlite3__wasm_pstack_restore,
/** /**
@@ -1186,7 +1195,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
configurable: false, iterable: true, writeable: false, configurable: false, iterable: true, writeable: false,
get: wasm.exports.sqlite3__wasm_pstack_ptr get: wasm.exports.sqlite3__wasm_pstack_ptr
//Whether or not a setter as an alternative to restore() is //Whether or not a setter as an alternative to restore() is
//clearer or would just lead to confusion is unclear. //clearer or would just lead to confusion or misuse is unclear.
//set: wasm.exports.sqlite3__wasm_pstack_restore //set: wasm.exports.sqlite3__wasm_pstack_restore
}, },
/** /**
@@ -1209,8 +1218,9 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
})/*wasm.pstack properties*/; })/*wasm.pstack properties*/;
capi.sqlite3_randomness = (...args)=>{ capi.sqlite3_randomness = (...args)=>{
if(1===args.length && util.isTypedArray(args[0]) if(1===args.length
&& 1===args[0].BYTES_PER_ELEMENT){ && util.isTypedArray(args[0])
&& 1===args[0].BYTES_PER_ELEMENT){
const ta = args[0]; const ta = args[0];
if(0===ta.byteLength){ if(0===ta.byteLength){
wasm.exports.sqlite3_randomness(0,0); wasm.exports.sqlite3_randomness(0,0);
@@ -1231,8 +1241,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
offset += j; offset += j;
} while(n > 0); } while(n > 0);
}catch(e){ }catch(e){
console.error("Highly unexpected (and ignored!) "+ config.error("Highly unexpected (and ignored!) "+
"exception in sqlite3_randomness():",e); "exception in sqlite3_randomness():",e);
}finally{ }finally{
wasm.pstack.restore(stack); wasm.pstack.restore(stack);
} }
@@ -1249,22 +1259,21 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
does not then it returns "" (noting that "" is a falsy value). does not then it returns "" (noting that "" is a falsy value).
The first time this is called, this function inspects the current The first time this is called, this function inspects the current
environment to determine whether persistence support is available environment to determine whether WASMFS persistence support is
and, if it is, enables it (if needed). After the first call it available and, if it is, enables it (if needed). After the first
always returns the cached result. call it always returns the cached result.
If the returned string is not empty, any files stored under the If the returned string is not empty, any files stored under the
given path (recursively) are housed in OPFS storage. If the returned path (recursively) are housed in OPFS storage. If the
returned string is empty, this particular persistent storage returned string is empty, this particular persistent storage
option is not available on the client. option is not available on the client.
Though the mount point name returned by this function is intended Though the mount point name returned by this function is intended
to remain stable, clients should not hard-coded it to remain stable, clients should not hard-coded it anywhere.
anywhere. Always call this function to get the path. Always call this function to get the path.
Note that this function is a no-op in most builds of this This function is a no-op in most builds of this library, as the
library, as the WASMFS capability requires a custom WASMFS capability requires a custom build.
build.
*/ */
capi.sqlite3_wasmfs_opfs_dir = function(){ capi.sqlite3_wasmfs_opfs_dir = function(){
if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir; if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
@@ -1273,7 +1282,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
if(!pdir if(!pdir
|| !globalThis.FileSystemHandle || !globalThis.FileSystemHandle
|| !globalThis.FileSystemDirectoryHandle || !globalThis.FileSystemDirectoryHandle
|| !globalThis.FileSystemFileHandle){ || !globalThis.FileSystemFileHandle
|| !wasm.exports.sqlite3__wasm_init_wasmfs){
return __wasmfsOpfsDir = ""; return __wasmfsOpfsDir = "";
} }
try{ try{
@@ -1305,11 +1315,10 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
(defaulting to "main"), returns a truthy value (see below) if (defaulting to "main"), returns a truthy value (see below) if
that db uses that VFS, else returns false. If pDb is falsy then that db uses that VFS, else returns false. If pDb is falsy then
the 3rd argument is ignored and this function returns a truthy the 3rd argument is ignored and this function returns a truthy
value if the default VFS name matches that of the 2nd value if the default VFS name matches that of the 2nd argument.
argument. Results are undefined if pDb is truthy but refers to an Results are undefined if pDb is truthy but refers to an invalid
invalid pointer. The 3rd argument specifies the database name of pointer. The 3rd argument specifies the database name of the
the given database connection to check, defaulting to the main given database connection to check, defaulting to the main db.
db.
The 2nd and 3rd arguments may either be a JS string or a WASM The 2nd and 3rd arguments may either be a JS string or a WASM
C-string. If the 2nd argument is a NULL WASM pointer, the default C-string. If the 2nd argument is a NULL WASM pointer, the default
@@ -1320,9 +1329,9 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
object. object.
To permit safe use of this function from APIs which may be called To permit safe use of this function from APIs which may be called
via the C stack (like SQL UDFs), this function does not throw: if via C (like SQL UDFs), this function does not throw: if bad
bad arguments cause a conversion error when passing into arguments cause a conversion error when passing into wasm-space,
wasm-space, false is returned. false is returned.
*/ */
capi.sqlite3_js_db_uses_vfs = function(pDb,vfsName,dbName=0){ capi.sqlite3_js_db_uses_vfs = function(pDb,vfsName,dbName=0){
try{ try{
@@ -1437,8 +1446,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
It may behave differently in other environments. It may behave differently in other environments.
The first argument must be either a JS string or WASM C-string The first argument must be either a JS string or WASM C-string
holding the filename. Note that this routine does _not_ create holding the filename. This routine does _not_ create intermediary
intermediary directories if the filename has a directory part. directories if the filename has a directory part.
The 2nd argument may either a valid WASM memory pointer, an The 2nd argument may either a valid WASM memory pointer, an
ArrayBuffer, or a Uint8Array. The 3rd must be the length, in ArrayBuffer, or a Uint8Array. The 3rd must be the length, in
@@ -1475,7 +1484,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code", if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
capi.sqlite3_js_rc_str(rc)); capi.sqlite3_js_rc_str(rc));
}finally{ }finally{
wasm.dealloc(pData); if( pData && pData!==data ) wasm.dealloc(pData);
} }
}; };
@@ -1484,12 +1493,13 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
debug builds of sqlite3 because its out-of-scope use of the debug builds of sqlite3 because its out-of-scope use of the
sqlite3_vfs API triggers assertions in the core library. That sqlite3_vfs API triggers assertions in the core library. That
was unfortunately not discovered until 2023-08-11. This function was unfortunately not discovered until 2023-08-11. This function
is now deprecated and should not be used in new code. is now deprecated. It should not be used in new code and should
be removed from existing code.
Alternative options: Alternative options:
- "unix" VFS and its variants can get equivalent functionality - The "unix" VFS and its variants can get equivalent
with sqlite3_js_posix_create_file(). functionality with sqlite3_js_posix_create_file().
- OPFS: use either sqlite3.oo1.OpfsDb.importDb(), for the "opfs" - OPFS: use either sqlite3.oo1.OpfsDb.importDb(), for the "opfs"
VFS, or the importDb() method of the PoolUtil object provided VFS, or the importDb() method of the PoolUtil object provided
@@ -1498,6 +1508,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
from here because the former is necessarily asynchronous and from here because the former is necessarily asynchronous and
the latter requires information not available to this function. the latter requires information not available to this function.
Historical (deprecated) behaviour:
Creates a file using the storage appropriate for the given Creates a file using the storage appropriate for the given
sqlite3_vfs. The first argument may be a VFS name (JS string sqlite3_vfs. The first argument may be a VFS name (JS string
only, NOT a WASM C-string), WASM-managed `sqlite3_vfs*`, or only, NOT a WASM C-string), WASM-managed `sqlite3_vfs*`, or
@@ -1540,7 +1552,10 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
- "unix" and related: will use the WASM build's equivalent of the - "unix" and related: will use the WASM build's equivalent of the
POSIX I/O APIs. This will work so long as neither a specific POSIX I/O APIs. This will work so long as neither a specific
VFS nor the WASM environment imposes requirements which break it. VFS nor the WASM environment imposes requirements which break
it. (Much later: it turns out that debug builds of the library
impose such requirements, in that they assert() that dataLen is
an even multiple of a valid db page size.)
- "opfs": uses OPFS storage and creates directory parts of the - "opfs": uses OPFS storage and creates directory parts of the
filename. It can only be used to import an SQLite3 database filename. It can only be used to import an SQLite3 database

View File

@@ -300,7 +300,10 @@ SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_alloc(int n){
** enough for general-purpose string conversions because some of our ** enough for general-purpose string conversions because some of our
** tests use input files (strings) of 16MB+. ** tests use input files (strings) of 16MB+.
*/ */
static unsigned char PStack_mem[512 * 8] = {0}; static unsigned char PStack_mem[
1024 * 4 /* API docs guaranty at least 2kb and it's been set at 4kb
since it was introduced. */
] = {0};
static struct { static struct {
unsigned const char * const pBegin;/* Start (inclusive) of memory */ unsigned const char * const pBegin;/* Start (inclusive) of memory */
unsigned const char * const pEnd; /* One-after-the-end of memory */ unsigned const char * const pEnd; /* One-after-the-end of memory */
@@ -401,7 +404,10 @@ void sqlite3__wasm_test_struct(WasmTestStruct * s){
*/ */
SQLITE_WASM_EXPORT SQLITE_WASM_EXPORT
const char * sqlite3__wasm_enum_json(void){ const char * sqlite3__wasm_enum_json(void){
static char aBuffer[1024 * 20] = {0} /* where the JSON goes */; static char aBuffer[1024 * 20] =
{0} /* where the JSON goes. 2025-09-19: output size=19295, but
that can vary slightly from build to build, so a little
leeway is needed here. */;
int n = 0, nChildren = 0, nStruct = 0 int n = 0, nChildren = 0, nStruct = 0
/* output counters for figuring out where commas go */; /* output counters for figuring out where commas go */;
char * zPos = &aBuffer[1] /* skip first byte for now to help protect char * zPos = &aBuffer[1] /* skip first byte for now to help protect
@@ -971,8 +977,8 @@ const char * sqlite3__wasm_enum_json(void){
** } ** }
** } ** }
** **
** Detailed documentation for those bits are in the docs for the ** Detailed documentation for those bits are in the Jaccwabyt
** Jaccwabyt JS-side component. ** JS-side component.
*/ */
/** Macros for emitting StructBinder description. */ /** Macros for emitting StructBinder description. */

View File

@@ -1352,7 +1352,7 @@ globalThis.WhWasmUtilInstaller = function(target){
The reason for the 2nd argument is... The reason for the 2nd argument is...
When one of the returned pointers will refer to a 64-bit value, When one of the returned pointers will refer to a 64-bit value,
e.g. a double or int64, an that value must be written or fetched, e.g. a double or int64, and that value must be written or fetched,
e.g. using poke() or peek(), it is important that e.g. using poke() or peek(), it is important that
the pointer in question be aligned to an 8-byte boundary or else the pointer in question be aligned to an 8-byte boundary or else
it will not be fetched or written properly and will corrupt or it will not be fetched or written properly and will corrupt or
@@ -1401,9 +1401,11 @@ globalThis.WhWasmUtilInstaller = function(target){
target.xCall = function(fname, ...args){ target.xCall = function(fname, ...args){
const f = (fname instanceof Function) ? fname : target.xGet(fname); const f = (fname instanceof Function) ? fname : target.xGet(fname);
if(!(f instanceof Function)) toss("Exported symbol",fname,"is not a function."); if(!(f instanceof Function)) toss("Exported symbol",fname,"is not a function.");
if(f.length!==args.length) __argcMismatch(((f===fname) ? f.name : fname),f.length) if(f.length!==args.length){
/* This is arguably over-pedantic but we want to help clients keep __argcMismatch(((f===fname) ? f.name : fname),f.length)
from shooting themselves in the foot when calling C APIs. */; /* This is arguably over-pedantic but we want to help clients keep
from shooting themselves in the foot when calling C APIs. */;
}
return (2===arguments.length && Array.isArray(arguments[1])) return (2===arguments.length && Array.isArray(arguments[1]))
? f.apply(null, arguments[1]) ? f.apply(null, arguments[1])
: f.apply(null, args); : f.apply(null, args);
@@ -1418,14 +1420,15 @@ globalThis.WhWasmUtilInstaller = function(target){
cache.xWrap.convert.arg = new Map; cache.xWrap.convert.arg = new Map;
/** Map of type names to return result conversion functions. */ /** Map of type names to return result conversion functions. */
cache.xWrap.convert.result = new Map; cache.xWrap.convert.result = new Map;
/** Scope-local convenience aliases. */
const xArg = cache.xWrap.convert.arg, xResult = cache.xWrap.convert.result; const xArg = cache.xWrap.convert.arg, xResult = cache.xWrap.convert.result;
if(target.bigIntEnabled){ if(target.bigIntEnabled){
xArg.set('i64', (i)=>BigInt(i)); xArg.set('i64', (i)=>BigInt(i));
} }
const __xArgPtr = 'i32' === ptrIR const __xArgPtr = ('i32' === ptrIR)
? ((i)=>(i | 0)) : ((i)=>(BigInt(i) | BigInt(0))); ? ((i)=>(i | 0)) : ((i)=>(BigInt(i) | BigInt(0)));
xArg.set('i32', __xArgPtr ) xArg.set('i32', (i)=>(i | 0) )
.set('i16', (i)=>((i | 0) & 0xFFFF)) .set('i16', (i)=>((i | 0) & 0xFFFF))
.set('i8', (i)=>((i | 0) & 0xFF)) .set('i8', (i)=>((i | 0) & 0xFF))
.set('f32', (i)=>Number(i).valueOf()) .set('f32', (i)=>Number(i).valueOf())
@@ -1445,8 +1448,8 @@ globalThis.WhWasmUtilInstaller = function(target){
.set(null, xResult.get('null')); .set(null, xResult.get('null'));
{ /* Copy xArg[...] handlers to xResult[...] for cases which have { /* Copy xArg[...] handlers to xResult[...] for cases which have
identical semantics. Also add pointer-style variants of identical semantics. Also add pointer-style variants of those
them. */ xArg entries to both xArg and xResult. */
const copyToResult = ['i8', 'i16', 'i32', 'int', const copyToResult = ['i8', 'i16', 'i32', 'int',
'f32', 'float', 'f64', 'double']; 'f32', 'float', 'f64', 'double'];
if(target.bigIntEnabled) copyToResult.push('i64'); if(target.bigIntEnabled) copyToResult.push('i64');
@@ -1905,11 +1908,11 @@ globalThis.WhWasmUtilInstaller = function(target){
which convert their argument to an integer and truncate it to which convert their argument to an integer and truncate it to
the given bit length. the given bit length.
- `*` and `pointer` (args): are assumed to be WASM pointer values - `*`, `**`, and `pointer` (args): are assumed to be WASM pointer
and are returned coerced to an appropriately-sized pointer values and are returned coerced to an appropriately-sized
value (i32 or i64). Non-numeric values will coerce to 0 and pointer value (i32 or i64). Non-numeric values will coerce to 0
out-of-range values will have undefined results (just as with and out-of-range values will have undefined results (just as
any pointer misuse). with any pointer misuse).
- `*` and `pointer` (results): aliases for the current - `*` and `pointer` (results): aliases for the current
WASM pointer numeric type. WASM pointer numeric type.
@@ -1934,9 +1937,9 @@ globalThis.WhWasmUtilInstaller = function(target){
distinguish between the two types of floating-point numbers. distinguish between the two types of floating-point numbers.
- `number` (results): converts the result to a JS Number using - `number` (results): converts the result to a JS Number using
Number(theValue).valueOf(). Note that this is for result Number(theValue). This is for result conversions only, as it's
conversions only, as it's not possible to generically know not possible to generically know which type of number to
which type of number to convert arguments to. convert arguments to.
Non-numeric conversions include: Non-numeric conversions include:
@@ -1948,7 +1951,7 @@ globalThis.WhWasmUtilInstaller = function(target){
to accommodate various uses of certain C APIs to accommodate various uses of certain C APIs
(e.g. output-style strings)... (e.g. output-style strings)...
- If the arg is a string, it creates a _temporary_ - If the arg is a JS string, it creates a _temporary_
UTF-8-encoded C-string to pass to the exported function, UTF-8-encoded C-string to pass to the exported function,
cleaning it up before the wrapper returns. If a long-lived cleaning it up before the wrapper returns. If a long-lived
C-string pointer is required, that requires client-side code C-string pointer is required, that requires client-side code
@@ -1965,10 +1968,10 @@ globalThis.WhWasmUtilInstaller = function(target){
- `string:dealloc` or `utf8:dealloc` (results): treats the result - `string:dealloc` or `utf8:dealloc` (results): treats the result
value as a non-const UTF-8 C-string, ownership of which has value as a non-const UTF-8 C-string, ownership of which has
just been transfered to the caller. It copies the C-string to a just been transfered to the caller. It copies the C-string to a
JS string, frees the C-string, and returns the JS string. If JS string, frees the C-string using dealloc(), and returns the
such a result value is NULL, the JS result is `null`. Achtung: JS string. If such a result value is NULL, the JS result is
when using an API which returns results from a specific `null`. Achtung: when using an API which returns results from a
allocator, e.g. `my_malloc()`, this conversion _is not specific allocator, e.g. `my_malloc()`, this conversion _is not
legal_. Instead, an equivalent conversion which uses the legal_. Instead, an equivalent conversion which uses the
appropriate deallocator is required. For example: appropriate deallocator is required. For example:

View File

@@ -1261,7 +1261,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
dw = sqlite3.oo1.DB.wrapHandle(pDb, true); dw = sqlite3.oo1.DB.wrapHandle(pDb, true);
pDb = 0; pDb = 0;
//sqlite3.config.debug("dw",dw); //sqlite3.config.debug("dw",dw);
T.assert( pTmp===dw.pointer, 'pDb===dw.pointer' ); T.assert( pTmp===dw.pointer, 'pTmp===dw.pointer' );
T.assert( dw.filename === "", "dw.filename == "+dw.filename ); T.assert( dw.filename === "", "dw.filename == "+dw.filename );
let q = dw.prepare("select 1"); let q = dw.prepare("select 1");
try { try {
@@ -3567,9 +3567,12 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
name: 'Delete via bound parameter in subquery', name: 'Delete via bound parameter in subquery',
predicate: ()=>wasm.compileOptionUsed('ENABLE_FTS5') || "Missing FTS5", predicate: ()=>wasm.compileOptionUsed('ENABLE_FTS5') || "Missing FTS5",
test: function(sqlite3){ test: function(sqlite3){
// Testing https://sqlite.org/forum/forumpost/40ce55bdf5 /**
// with the exception that that post uses "external content" Testing https://sqlite.org/forum/forumpost/40ce55bdf5 with
// for the FTS index. the exception that that post uses "external content" for
the FTS index. This isn't testing a fix, just confirming
that the bug report is not really a bug.
*/
const db = new sqlite3.oo1.DB();//(':memory:','wt'); const db = new sqlite3.oo1.DB();//(':memory:','wt');
db.exec([ db.exec([
"create virtual table f using fts5 (path);", "create virtual table f using fts5 (path);",
@@ -3586,10 +3589,10 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
//dump('Full fts table'); //dump('Full fts table');
let rc = fetchEm(); let rc = fetchEm();
T.assert(3===rc.length); T.assert(3===rc.length);
db.exec(` db.exec(
delete from f where rowid in ( ["delete from f where rowid in (",
select rowid from f where path = :path "select rowid from f where path = :path",
)`, ")"],
{bind: {":path": "def"}} {bind: {":path": "def"}}
); );
//dump('After deleting one entry via subquery'); //dump('After deleting one entry via subquery');

View File

@@ -1,5 +1,5 @@
C Wasm:\s(A)\sdiverse\sinternal\sdoc\supdates.\s(B)\swhen\sgenerating\sautomated\sJS-to-WASM\sfunction\sproxies\sfor\sconverters\swhich\srequire\san\sadditional\smiddle-man\sproxy,\se.g.\ssqlite3_exec(),\suse\sthe\sclient-provided\sfunction,\snot\sthe\sproxy\sfunction,\sas\sthe\scache\skey,\sto\skeep\sfrom\sre-generating\sthe\sconversion\sin\ssome\scommon\suse\spatterns. C Diverse\scleanups\sand\sdocs\sin\sthe\sJS\sand\skvvfs\spieces.\sFunctional\schanges:\s(A)\sensure\sthat\sthe\s'i32'\sJS/WASM\sfunc\sarg/result\sconversion\sworks\sproperly\swith\sa\s64-bit-memory\sWASM\sbuild\s(which\swe\sneither\suse\snor\stest\sbut\s[https://webassembly.org/news/2025-09-17-wasm-3.0/\s|\sthe\snewly-ratified\sWASM\s3.0]\sbrings\swithin\spotential\sreach).\s(B)\sFix\ssqlite3_js_posix_create_file()\sto\snot\sdeallocate\sits\sinput\sarray\sif\sthe\sclient\spasses\sin\sraw\smemory\s(the\slibrary\shas\snever\sused\sit\sthat\sway\sbut\sthe\sAPI\spermits\sit).
D 2025-09-19T14:21:09.961 D 2025-09-19T17:24:47.155
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -597,9 +597,9 @@ F ext/wasm/api/post-js-footer.js 365405929f41ca0e6d389ed8a8da3f3c93e11d3ef43a90a
F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701 F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701
F ext/wasm/api/pre-js.c-pp.js 58f823de197e2c10d76179aa05410a593b7ae03e1ece983bb42ffd818e8857e1 F ext/wasm/api/pre-js.c-pp.js 58f823de197e2c10d76179aa05410a593b7ae03e1ece983bb42ffd818e8857e1
F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359
F ext/wasm/api/sqlite3-api-glue.c-pp.js 066c09125d12189863ec2b34e702b7b8a7ba25c00e73f77de0b727430ef65687 F ext/wasm/api/sqlite3-api-glue.c-pp.js fab9a05257119d42f3d26cf4e437198a8c479d2c4751c5de4ac986969bd3dd4b
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 852f2cd6acddbae487fc4f1c3ec952e6c1e2033aa4e6c7091d330d983c87c032 F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc8573267f0dd49ae314a295c0dbe86de921f6d6beabbb7a447029ca1ea4e1d9
F ext/wasm/api/sqlite3-api-prologue.js 4272131346b102d6f1bfc07524331213ff89407b76cbbde4c0b48b19c692ba94 F ext/wasm/api/sqlite3-api-prologue.js 332bcf0c8a32af38c8b2f308b1cb37002e1db3ec27df9fe629116a591540e375
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 760191cd13416e6f5adfd9fcc8a97fed5645c9e0a5fbac213a2d4ce2d79a4334 F ext/wasm/api/sqlite3-api-worker1.c-pp.js 760191cd13416e6f5adfd9fcc8a97fed5645c9e0a5fbac213a2d4ce2d79a4334
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
@@ -607,7 +607,7 @@ F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 0f68a64e508598910e7c01214ae27d603dfc8baec6a184506fafac603a901931 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 0f68a64e508598910e7c01214ae27d603dfc8baec6a184506fafac603a901931
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4ab0704ee198de7d1059eccedc7703c931510b588d10af0ee36ea5b3ebbac284 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4ab0704ee198de7d1059eccedc7703c931510b588d10af0ee36ea5b3ebbac284
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616
F ext/wasm/api/sqlite3-wasm.c 404cc1f0f5c307210a8d7c3a7dda57834e0e8b3d406ba51977a97a6d14a74734 F ext/wasm/api/sqlite3-wasm.c c60f778e686a47279885b55345abefd3cf2a1da24c1921e530081444aec68a6e
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 4ad256b4ff7f839ad18931ed35d46cced544207bd2209665ec552e193f7f4544 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 4ad256b4ff7f839ad18931ed35d46cced544207bd2209665ec552e193f7f4544
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5 F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7 F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7
@@ -618,7 +618,7 @@ F ext/wasm/c-pp.c cca55c5b55ebd8d29916adbedb0e40baa12caa9a2e8429f812683c308f9b0e
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51 F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
F ext/wasm/common/whwasmutil.js 4ea5a413016d9a561a26976c699a2670f2385b93be04cd2d463dd6c1955bd175 F ext/wasm/common/whwasmutil.js 000232b0a9527af5a73b3c0e46ef91a19517ae027ce73fd8902f06c490b9b97c
F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
@@ -655,7 +655,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
F ext/wasm/tester1.c-pp.js aa694096feb5cfd9333f7029e933a4eae95bde5cc3edd29da4dc0f8dae452905 F ext/wasm/tester1.c-pp.js de2736de2335a74a9ecbda9005af5c8b1c33fd8729591064ef4795650da65900
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -725,7 +725,7 @@ F src/notify.c 57c2d1a2805d6dee32acd5d250d928ab94e02d76369ae057dee7d445fd64e878
F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_kv.c fb7ba8d6204197357f1eb7e1c7450d09c10043bf7e99aba602f4aa46b8fb11a3
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c b3da55bc4bb214b2bfb1e430b10e9d3ebcf6b11741921ab044c9b9539c8fcc4f F src/os_unix.c b3da55bc4bb214b2bfb1e430b10e9d3ebcf6b11741921ab044c9b9539c8fcc4f
F src/os_win.c f81a7cffdfe8c593a840895b3f64290714f0186b06302d2c397012252d830374 F src/os_win.c f81a7cffdfe8c593a840895b3f64290714f0186b06302d2c397012252d830374
@@ -2175,8 +2175,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 468a11fd415710042b23880772f6c2c7771008208823fe3b554227a9244dbf92 P 5e5139c2a162562cee0071d03954ebc0b8938da0b045ec3f5eba32dc8e19604d
R 45b30de6d5f1d826a12d811876f55290 R 39374a1a28932b274e07d195dbea9d94
U stephan U stephan
Z 31a53fb96f385e882a14f4d3fa47d2d3 Z 8c740e2b096da4198cfd5683f58d6ede
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
5e5139c2a162562cee0071d03954ebc0b8938da0b045ec3f5eba32dc8e19604d 79af65a694fbbb3d501fb2ebd835c259ca644e0dafdd71eeb9f0a7c0e9128a1e

View File

@@ -174,7 +174,7 @@ static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf);
#define KVSTORAGE_KEY_SZ 32 #define KVSTORAGE_KEY_SZ 32
/* Expand the key name with an appropriate prefix and put the result /* Expand the key name with an appropriate prefix and put the result
** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least ** in zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least
** KVSTORAGE_KEY_SZ bytes. ** KVSTORAGE_KEY_SZ bytes.
*/ */
static void kvstorageMakeKey( static void kvstorageMakeKey(
@@ -233,10 +233,12 @@ static int kvstorageDelete(const char *zClass, const char *zKey){
** **
** Return the total number of bytes in the data, without truncation, and ** Return the total number of bytes in the data, without truncation, and
** not counting the final zero terminator. Return -1 if the key does ** not counting the final zero terminator. Return -1 if the key does
** not exist. ** not exist or its key cannot be read.
** **
** If nBuf<=0 then this routine simply returns the size of the data without ** If nBuf<=0 then this routine simply returns the size of the data
** actually reading it. ** without actually reading it. Similarly, if nBuf==1 then it
** zero-terminates zBuf at zBuf[0] and returns the size of the data
** without reading it.
*/ */
static int kvstorageRead( static int kvstorageRead(
const char *zClass, const char *zClass,
@@ -285,11 +287,9 @@ static int kvstorageRead(
** kvvfs i/o methods with JavaScript implementations in WASM builds. ** kvvfs i/o methods with JavaScript implementations in WASM builds.
** Maintenance reminder: if this struct changes in any way, the JSON ** Maintenance reminder: if this struct changes in any way, the JSON
** rendering of its structure must be updated in ** rendering of its structure must be updated in
** sqlite3_wasm_enum_json(). There are no binary compatibility ** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary
** concerns, so it does not need an iVersion member. This file is ** compatibility concerns, so it does not need an iVersion
** necessarily always compiled together with sqlite3_wasm_enum_json(), ** member.
** and JS code dynamically creates the mapping of members based on
** that JSON description.
*/ */
typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods;
struct sqlite3_kvvfs_methods { struct sqlite3_kvvfs_methods {
@@ -306,8 +306,8 @@ struct sqlite3_kvvfs_methods {
** the compiler can hopefully optimize this level of indirection out. ** the compiler can hopefully optimize this level of indirection out.
** That said, kvvfs is intended primarily for use in WASM builds. ** That said, kvvfs is intended primarily for use in WASM builds.
** **
** Note that this is not explicitly flagged as static because the ** This is not explicitly flagged as static because the amalgamation
** amalgamation build will tag it with SQLITE_PRIVATE. ** build will tag it with SQLITE_PRIVATE.
*/ */
#ifndef SQLITE_WASM #ifndef SQLITE_WASM
const const