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:
@@ -243,21 +243,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
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, [
|
||||
@@ -323,7 +323,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["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
|
||||
@@ -375,7 +375,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
]],
|
||||
["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
|
||||
@@ -435,12 +435,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
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;
|
||||
}
|
||||
@@ -470,12 +475,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
//#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"],
|
||||
@@ -496,12 +502,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["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", "**"]
|
||||
@@ -713,7 +719,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}/*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({
|
||||
@@ -722,7 +728,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
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;
|
||||
|
||||
@@ -745,16 +753,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
- 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',
|
||||
@@ -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('*');
|
||||
wasm.xWrap.resultAdapter('sqlite3*', __xRcPtr)
|
||||
('sqlite3_context*', __xRcPtr)
|
||||
@@ -834,15 +848,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
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);
|
||||
}
|
||||
@@ -854,18 +859,16 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
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;
|
||||
@@ -949,6 +952,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
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:
|
||||
@@ -968,7 +972,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}
|
||||
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',
|
||||
|
||||
Reference in New Issue
Block a user