purpose. For example:
const pAuxDtor = wasm.installFunction('v(p)', function(ptr){
- //free ptr
+ //free ptr
});
myDb.onclose = {
- after: ()=>{
- wasm.uninstallFunction(pAuxDtor);
- }
+ after: ()=>{
+ wasm.uninstallFunction(pAuxDtor);
+ }
};
Then pass pAuxDtor as the final argument to appropriate
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
- working. Rather than fix it, it was removed because testing the
- fix brought the huge potential for memory leaks to the
+ working. Rather than fix it, it was removed because testing
+ the fix brought the huge potential for memory leaks to the
forefront.
*/
["sqlite3_set_auxdata", undefined, [
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
- /* This list gets extended below */
+ /* This list gets extended with optional pieces below */
]/*.core*/,
/**
Functions which require BigInt (int64) support are separated
]],
["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]],
["sqlite3_value_int64","i64", "sqlite3_value*"]
- /* This list gets extended below */
+ /* This list gets extended with optional pieces below */
]/*.int64*/,
/**
Functions which are intended solely for API-internal use by the
name: "sqlite3_set_authorizer::xAuth",
signature: "i(pi"+"ssss)",
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)=>{
return (pV, iCode, s0, s1, s2, s3)=>{
try{
s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1);
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){
return e.resultCode || capi.SQLITE_ERROR;
}
//#if enable-see
if( !!wasm.exports.sqlite3_key_v2 ){
/**
- This code is capable of using an SEE build but note that an SEE
- WASM build is generally incompatible with SEE's license
- conditions. It is permitted for use internally in organizations
- which have licensed SEE, but not for public sites because
- exposing an SEE build of sqlite3.wasm effectively provides all
- clients with a working copy of the commercial SEE code.
+ This code is capable of using an SEE build but an SEE WASM
+ build is generally incompatible with SEE's license conditions.
+ The project's official stance on WASM builds of SEE is: it is
+ permitted for use internally within organizations which have
+ licensed SEE, but not for public sites because exposing an SEE
+ build of sqlite3.wasm effectively provides all clients with a
+ working copy of SEE.
*/
bindingSignatures.core.push(
["sqlite3_key", "int", "sqlite3*", "string", "int"],
["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]],
["sqlite3_drop_modules", "int", ["sqlite3*", "**"]],
["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_in","int", "sqlite3_index_info*", "int", "int"],
["sqlite3_vtab_in_first", "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_on_conflict","int", "sqlite3*"],
["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"]
}/*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...
*/
sqlite3.StructBinder = globalThis.Jaccwabyt({
dealloc: wasm.dealloc,
bigIntEnabled: wasm.bigIntEnabled,
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;
- 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
returned, else wasm.allocCString() is used to create a a new
- string, map its pointer to (''+v) for the remainder of the
- application's life, and returns that pointer value for this
- call and all future calls which are passed a
+ string, map its pointer to a copy of (''+v) for the remainder
+ of the application's life, and returns that pointer value for
+ this call and all future calls which are passed a
string-equivalent argument.
- Use case: sqlite3_bind_pointer() and sqlite3_result_pointer()
- call for "a static string and preferably a string
- literal." This converter is used to ensure that the string
- value seen by those functions is long-lived and behaves as they
- need it to.
+ Use case: sqlite3_bind_pointer(), sqlite3_result_pointer(), and
+ sqlite3_value_pointer() call for "a static string and
+ preferably a string literal". This converter is used to ensure
+ that the string value seen by those functions is long-lived and
+ behaves as they need it to, at the cost of a one-time leak of
+ each distinct key.
*/
wasm.xWrap.argAdapter(
'string:static',
);
}
+ /**
+ Alias `T*` to `*` for return type conversions for common T
+ types, primarily to improve legibility of their binding
+ signatures.
+ */
const __xRcPtr = wasm.xWrap.resultAdapter('*');
wasm.xWrap.resultAdapter('sqlite3*', __xRcPtr)
('sqlite3_context*', __xRcPtr)
Populate api object with sqlite3_...() by binding the "raw" wasm
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){
capi[e[0]] = wasm.xWrap.apply(null, e);
}
wasm.bigIntEnabled is true, install a bogus impl which throws
if called when bigIntEnabled is false. The alternative would be
to elide these functions altogether, which seems likely to
- cause more confusion. */
- const fI64Disabled = function(fname){
- return ()=>toss(fname+"() is unavailable due to lack",
- "of BigInt support in this build.");
- };
+ cause more confusion, as documented APIs would resolve to the
+ undefined value in incompatible builds. */
for(const e of bindingSignatures.int64){
capi[e[0]] = wasm.bigIntEnabled
? 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.int64;
delete bindingSignatures.wasmInternal;
string, or undefined if no such mapping is found.
*/
capi.sqlite3_js_rc_str = (rc)=>__rcMap[rc];
+
/* Bind all registered C-side structs... */
const notThese = Object.assign(Object.create(null),{
// For each struct to NOT register, map its name to true:
}
if(capi.sqlite3_index_info){
/* 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
** passed them to StructBinder. */
for(const k of ['sqlite3_index_constraint',
closed when onclose.after is called. If this db is not opened
when close() is called, neither of the handlers are called. Any
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
- all, will never trigger close(), so onclose handlers are not a
- reliable way to implement close-time cleanup or maintenance of
- a db.
+ Garbage collection of a db handle, if it happens at all, will
+ never trigger close(), so onclose handlers are not a reliable
+ way to implement close-time cleanup or maintenance of a db.
If this instance was created using DB.wrapHandle() and does not
own this.pointer then it does not close the db handle but it
}/*compileOptionUsed()*/;
/**
- sqlite3.wasm.pstack (pseudo-stack) holds a special-case
- stack-style allocator intended only for use with _small_ data of
- not more than (in total) a few kb in size, managed as if it were
- stack-based.
+ sqlite3.wasm.pstack (pseudo-stack) holds a special-case intended
+ solely for short-lived, small data. In practice, it's primarily
+ used to allocate output pointers. It mus not be used for any
+ 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:
Sets the current pstack position to the given pointer. Results
are undefined if the passed-in value did not come from
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,
/**
configurable: false, iterable: true, writeable: false,
get: wasm.exports.sqlite3__wasm_pstack_ptr
//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
},
/**
})/*wasm.pstack properties*/;
capi.sqlite3_randomness = (...args)=>{
- if(1===args.length && util.isTypedArray(args[0])
- && 1===args[0].BYTES_PER_ELEMENT){
+ if(1===args.length
+ && util.isTypedArray(args[0])
+ && 1===args[0].BYTES_PER_ELEMENT){
const ta = args[0];
if(0===ta.byteLength){
wasm.exports.sqlite3_randomness(0,0);
offset += j;
} while(n > 0);
}catch(e){
- console.error("Highly unexpected (and ignored!) "+
- "exception in sqlite3_randomness():",e);
+ config.error("Highly unexpected (and ignored!) "+
+ "exception in sqlite3_randomness():",e);
}finally{
wasm.pstack.restore(stack);
}
does not then it returns "" (noting that "" is a falsy value).
The first time this is called, this function inspects the current
- environment to determine whether persistence support is available
- and, if it is, enables it (if needed). After the first call it
- always returns the cached result.
+ environment to determine whether WASMFS persistence support is
+ available and, if it is, enables it (if needed). After the first
+ call it always returns the cached result.
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
option is not available on the client.
Though the mount point name returned by this function is intended
- to remain stable, clients should not hard-coded it
- anywhere. Always call this function to get the path.
+ to remain stable, clients should not hard-coded it anywhere.
+ Always call this function to get the path.
- Note that this function is a no-op in most builds of this
- library, as the WASMFS capability requires a custom
- build.
+ This function is a no-op in most builds of this library, as the
+ WASMFS capability requires a custom build.
*/
capi.sqlite3_wasmfs_opfs_dir = function(){
if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
if(!pdir
|| !globalThis.FileSystemHandle
|| !globalThis.FileSystemDirectoryHandle
- || !globalThis.FileSystemFileHandle){
+ || !globalThis.FileSystemFileHandle
+ || !wasm.exports.sqlite3__wasm_init_wasmfs){
return __wasmfsOpfsDir = "";
}
try{
(defaulting to "main"), returns a truthy value (see below) if
that db uses that VFS, else returns false. If pDb is falsy then
the 3rd argument is ignored and this function returns a truthy
- value if the default VFS name matches that of the 2nd
- argument. Results are undefined if pDb is truthy but refers to an
- invalid pointer. The 3rd argument specifies the database name of
- the given database connection to check, defaulting to the main
- db.
+ value if the default VFS name matches that of the 2nd argument.
+ Results are undefined if pDb is truthy but refers to an invalid
+ pointer. The 3rd argument specifies the database name of the
+ given database connection to check, defaulting to the main db.
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
object.
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
- bad arguments cause a conversion error when passing into
- wasm-space, false is returned.
+ via C (like SQL UDFs), this function does not throw: if bad
+ arguments cause a conversion error when passing into wasm-space,
+ false is returned.
*/
capi.sqlite3_js_db_uses_vfs = function(pDb,vfsName,dbName=0){
try{
It may behave differently in other environments.
The first argument must be either a JS string or WASM C-string
- holding the filename. Note that this routine does _not_ create
- intermediary directories if the filename has a directory part.
+ holding the filename. This routine does _not_ create intermediary
+ directories if the filename has a directory part.
The 2nd argument may either a valid WASM memory pointer, an
ArrayBuffer, or a Uint8Array. The 3rd must be the length, in
if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
capi.sqlite3_js_rc_str(rc));
}finally{
- wasm.dealloc(pData);
+ if( pData && pData!==data ) wasm.dealloc(pData);
}
};
debug builds of sqlite3 because its out-of-scope use of the
sqlite3_vfs API triggers assertions in the core library. That
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:
- - "unix" VFS and its variants can get equivalent functionality
- with sqlite3_js_posix_create_file().
+ - The "unix" VFS and its variants can get equivalent
+ functionality with sqlite3_js_posix_create_file().
- OPFS: use either sqlite3.oo1.OpfsDb.importDb(), for the "opfs"
VFS, or the importDb() method of the PoolUtil object provided
from here because the former is necessarily asynchronous and
the latter requires information not available to this function.
+ Historical (deprecated) behaviour:
+
Creates a file using the storage appropriate for the given
sqlite3_vfs. The first argument may be a VFS name (JS string
only, NOT a WASM C-string), WASM-managed `sqlite3_vfs*`, or
- "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
- 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
filename. It can only be used to import an SQLite3 database
** enough for general-purpose string conversions because some of our
** 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 {
unsigned const char * const pBegin;/* Start (inclusive) of memory */
unsigned const char * const pEnd; /* One-after-the-end of memory */
*/
SQLITE_WASM_EXPORT
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
/* output counters for figuring out where commas go */;
char * zPos = &aBuffer[1] /* skip first byte for now to help protect
** }
** }
**
- ** Detailed documentation for those bits are in the docs for the
- ** Jaccwabyt JS-side component.
+ ** Detailed documentation for those bits are in the Jaccwabyt
+ ** JS-side component.
*/
/** Macros for emitting StructBinder description. */
The reason for the 2nd argument is...
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
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
target.xCall = function(fname, ...args){
const f = (fname instanceof Function) ? fname : target.xGet(fname);
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)
- /* This is arguably over-pedantic but we want to help clients keep
- from shooting themselves in the foot when calling C APIs. */;
+ if(f.length!==args.length){
+ __argcMismatch(((f===fname) ? f.name : fname),f.length)
+ /* 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]))
? f.apply(null, arguments[1])
: f.apply(null, args);
cache.xWrap.convert.arg = new Map;
/** Map of type names to return result conversion functions. */
cache.xWrap.convert.result = new Map;
+ /** Scope-local convenience aliases. */
const xArg = cache.xWrap.convert.arg, xResult = cache.xWrap.convert.result;
if(target.bigIntEnabled){
xArg.set('i64', (i)=>BigInt(i));
}
- const __xArgPtr = 'i32' === ptrIR
+ const __xArgPtr = ('i32' === ptrIR)
? ((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('i8', (i)=>((i | 0) & 0xFF))
.set('f32', (i)=>Number(i).valueOf())
.set(null, xResult.get('null'));
{ /* Copy xArg[...] handlers to xResult[...] for cases which have
- identical semantics. Also add pointer-style variants of
- them. */
+ identical semantics. Also add pointer-style variants of those
+ xArg entries to both xArg and xResult. */
const copyToResult = ['i8', 'i16', 'i32', 'int',
'f32', 'float', 'f64', 'double'];
if(target.bigIntEnabled) copyToResult.push('i64');
which convert their argument to an integer and truncate it to
the given bit length.
- - `*` and `pointer` (args): are assumed to be WASM pointer values
- and are returned coerced to an appropriately-sized pointer
- value (i32 or i64). Non-numeric values will coerce to 0 and
- out-of-range values will have undefined results (just as with
- any pointer misuse).
+ - `*`, `**`, and `pointer` (args): are assumed to be WASM pointer
+ values and are returned coerced to an appropriately-sized
+ pointer value (i32 or i64). Non-numeric values will coerce to 0
+ and out-of-range values will have undefined results (just as
+ with any pointer misuse).
- `*` and `pointer` (results): aliases for the current
WASM pointer numeric type.
distinguish between the two types of floating-point numbers.
- `number` (results): converts the result to a JS Number using
- Number(theValue).valueOf(). Note that this is for result
- conversions only, as it's not possible to generically know
- which type of number to convert arguments to.
+ Number(theValue). This is for result conversions only, as it's
+ not possible to generically know which type of number to
+ convert arguments to.
Non-numeric conversions include:
to accommodate various uses of certain C APIs
(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,
cleaning it up before the wrapper returns. If a long-lived
C-string pointer is required, that requires client-side code
- `string:dealloc` or `utf8:dealloc` (results): treats the result
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
- JS string, frees the C-string, and returns the JS string. If
- such a result value is NULL, the JS result is `null`. Achtung:
- when using an API which returns results from a specific
- allocator, e.g. `my_malloc()`, this conversion _is not
+ JS string, frees the C-string using dealloc(), and returns the
+ JS string. If such a result value is NULL, the JS result is
+ `null`. Achtung: when using an API which returns results from a
+ specific allocator, e.g. `my_malloc()`, this conversion _is not
legal_. Instead, an equivalent conversion which uses the
appropriate deallocator is required. For example:
dw = sqlite3.oo1.DB.wrapHandle(pDb, true);
pDb = 0;
//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 );
let q = dw.prepare("select 1");
try {
name: 'Delete via bound parameter in subquery',
predicate: ()=>wasm.compileOptionUsed('ENABLE_FTS5') || "Missing FTS5",
test: function(sqlite3){
- // Testing https://sqlite.org/forum/forumpost/40ce55bdf5
- // with the exception that that post uses "external content"
- // for the FTS index.
+ /**
+ Testing https://sqlite.org/forum/forumpost/40ce55bdf5 with
+ 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');
db.exec([
"create virtual table f using fts5 (path);",
//dump('Full fts table');
let rc = fetchEm();
T.assert(3===rc.length);
- db.exec(`
- delete from f where rowid in (
- select rowid from f where path = :path
- )`,
+ db.exec(
+ ["delete from f where rowid in (",
+ "select rowid from f where path = :path",
+ ")"],
{bind: {":path": "def"}}
);
//dump('After deleting one entry via subquery');
-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.
-D 2025-09-19T14:21:09.961
+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-19T17:24:47.155
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701
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-glue.c-pp.js 066c09125d12189863ec2b34e702b7b8a7ba25c00e73f77de0b727430ef65687
-F ext/wasm/api/sqlite3-api-oo1.c-pp.js 852f2cd6acddbae487fc4f1c3ec952e6c1e2033aa4e6c7091d330d983c87c032
-F ext/wasm/api/sqlite3-api-prologue.js 4272131346b102d6f1bfc07524331213ff89407b76cbbde4c0b48b19c692ba94
+F ext/wasm/api/sqlite3-api-glue.c-pp.js fab9a05257119d42f3d26cf4e437198a8c479d2c4751c5de4ac986969bd3dd4b
+F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc8573267f0dd49ae314a295c0dbe86de921f6d6beabbb7a447029ca1ea4e1d9
+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-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
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-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.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
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/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
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/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
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_unix.c b3da55bc4bb214b2bfb1e430b10e9d3ebcf6b11741921ab044c9b9539c8fcc4f
F src/os_win.c f81a7cffdfe8c593a840895b3f64290714f0186b06302d2c397012252d830374
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 468a11fd415710042b23880772f6c2c7771008208823fe3b554227a9244dbf92
-R 45b30de6d5f1d826a12d811876f55290
+P 5e5139c2a162562cee0071d03954ebc0b8938da0b045ec3f5eba32dc8e19604d
+R 39374a1a28932b274e07d195dbea9d94
U stephan
-Z 31a53fb96f385e882a14f4d3fa47d2d3
+Z 8c740e2b096da4198cfd5683f58d6ede
# Remove this line to create a well-formed Fossil manifest.
-5e5139c2a162562cee0071d03954ebc0b8938da0b045ec3f5eba32dc8e19604d
+79af65a694fbbb3d501fb2ebd835c259ca644e0dafdd71eeb9f0a7c0e9128a1e
#define KVSTORAGE_KEY_SZ 32
/* 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.
*/
static void kvstorageMakeKey(
**
** 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 exist.
+** not exist or its key cannot be read.
**
-** If nBuf<=0 then this routine simply returns the size of the data without
-** actually reading it.
+** If nBuf<=0 then this routine simply returns the size of the data
+** 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(
const char *zClass,
** kvvfs i/o methods with JavaScript implementations in WASM builds.
** Maintenance reminder: if this struct changes in any way, the JSON
** rendering of its structure must be updated in
-** sqlite3_wasm_enum_json(). There are no binary compatibility
-** concerns, so it does not need an iVersion member. This file is
-** necessarily always compiled together with sqlite3_wasm_enum_json(),
-** and JS code dynamically creates the mapping of members based on
-** that JSON description.
+** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary
+** compatibility concerns, so it does not need an iVersion
+** member.
*/
typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods;
struct sqlite3_kvvfs_methods {
** the compiler can hopefully optimize this level of indirection out.
** That said, kvvfs is intended primarily for use in WASM builds.
**
-** Note that this is not explicitly flagged as static because the
-** amalgamation build will tag it with SQLITE_PRIVATE.
+** This is not explicitly flagged as static because the amalgamation
+** build will tag it with SQLITE_PRIVATE.
*/
#ifndef SQLITE_WASM
const