mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Minor cleanups and additions in sqlite3.capi.wasm.pstack.
FossilOrigin-Name: 97bd670d3859bd3f2e62c15065b238b85ef614f26479e56a14be42c5784aedf4
This commit is contained in:
@ -560,56 +560,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
};
|
};
|
||||||
}/*sqlite3_prepare_v2/v3()*/;
|
}/*sqlite3_prepare_v2/v3()*/;
|
||||||
|
|
||||||
if(1){// Extend wasm.pstack, now that the wasm utils are installed
|
|
||||||
/**
|
|
||||||
Allocates n chunks, each sz bytes, as a single memory block and
|
|
||||||
returns the addresses as an array of n element, each holding
|
|
||||||
the address of one chunk.
|
|
||||||
|
|
||||||
Throws a WasmAllocError if allocation fails.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
const [p1, p2, p3] = wasm.pstack.allocChunks(3,4);
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
wasm.pstack.allocChunks = (n,sz)=>{
|
|
||||||
const mem = wasm.pstack.alloc(n * sz);
|
|
||||||
const rc = [];
|
|
||||||
let i = 0, offset = 0;
|
|
||||||
for(; i < n; offset = (sz * ++i)){
|
|
||||||
rc.push(mem + offset);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
A convenience wrapper for allocChunks() which sizes each chunks
|
|
||||||
as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
|
|
||||||
safePtrSize is falsy).
|
|
||||||
|
|
||||||
How it returns its result differs depending on its first
|
|
||||||
argument: if it's 1, it returns a single pointer value. If it's
|
|
||||||
more than 1, it returns the same as allocChunks().
|
|
||||||
|
|
||||||
When a returned pointers will refer to a 64-bit value, e.g. a
|
|
||||||
double or int64, and that value must be written or fetched,
|
|
||||||
e.g. using wasm.setMemValue() or wasm.getMemValue(), 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 read neighboring memory.
|
|
||||||
|
|
||||||
However, when all pointers involved point to "small" data, it
|
|
||||||
is safe to pass a falsy value to save to memory.
|
|
||||||
*/
|
|
||||||
wasm.pstack.allocPtr = (n=1,safePtrSize=true) =>{
|
|
||||||
return 1===n
|
|
||||||
? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
|
|
||||||
: wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
|
|
||||||
};
|
|
||||||
}/*wasm.pstack filler*/
|
|
||||||
|
|
||||||
{/* Import C-level constants and structs... */
|
{/* Import C-level constants and structs... */
|
||||||
const cJson = wasm.xCall('sqlite3_wasm_enum_json');
|
const cJson = wasm.xCall('sqlite3_wasm_enum_json');
|
||||||
if(!cJson){
|
if(!cJson){
|
||||||
|
@ -610,12 +610,14 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
}/*wasm*/
|
}/*wasm*/
|
||||||
}/*capi*/;
|
}/*capi*/;
|
||||||
|
|
||||||
|
const wasm = capi.wasm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
capi.wasm.alloc()'s srcTypedArray.byteLength bytes,
|
wasm.alloc()'s srcTypedArray.byteLength bytes,
|
||||||
populates them with the values from the source
|
populates them with the values from the source
|
||||||
TypedArray, and returns the pointer to that memory. The
|
TypedArray, and returns the pointer to that memory. The
|
||||||
returned pointer must eventually be passed to
|
returned pointer must eventually be passed to
|
||||||
capi.wasm.dealloc() to clean it up.
|
wasm.dealloc() to clean it up.
|
||||||
|
|
||||||
As a special case, to avoid further special cases where
|
As a special case, to avoid further special cases where
|
||||||
this is used, if srcTypedArray.byteLength is 0, it
|
this is used, if srcTypedArray.byteLength is 0, it
|
||||||
@ -628,27 +630,27 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
Int8Array types and will throw if srcTypedArray is of
|
Int8Array types and will throw if srcTypedArray is of
|
||||||
any other type.
|
any other type.
|
||||||
*/
|
*/
|
||||||
capi.wasm.allocFromTypedArray = function(srcTypedArray){
|
wasm.allocFromTypedArray = function(srcTypedArray){
|
||||||
affirmBindableTypedArray(srcTypedArray);
|
affirmBindableTypedArray(srcTypedArray);
|
||||||
const pRet = capi.wasm.alloc(srcTypedArray.byteLength || 1);
|
const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
|
||||||
capi.wasm.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
|
wasm.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
|
||||||
return pRet;
|
return pRet;
|
||||||
};
|
};
|
||||||
|
|
||||||
const keyAlloc = config.allocExportName || 'malloc',
|
const keyAlloc = config.allocExportName || 'malloc',
|
||||||
keyDealloc = config.deallocExportName || 'free';
|
keyDealloc = config.deallocExportName || 'free';
|
||||||
for(const key of [keyAlloc, keyDealloc]){
|
for(const key of [keyAlloc, keyDealloc]){
|
||||||
const f = capi.wasm.exports[key];
|
const f = wasm.exports[key];
|
||||||
if(!(f instanceof Function)) toss("Missing required exports[",key,"] function.");
|
if(!(f instanceof Function)) toss("Missing required exports[",key,"] function.");
|
||||||
}
|
}
|
||||||
|
|
||||||
capi.wasm.alloc = function(n){
|
wasm.alloc = function(n){
|
||||||
const m = capi.wasm.exports[keyAlloc](n);
|
const m = wasm.exports[keyAlloc](n);
|
||||||
if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
|
if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
|
||||||
return m;
|
return m;
|
||||||
};
|
};
|
||||||
|
|
||||||
capi.wasm.dealloc = (m)=>capi.wasm.exports[keyDealloc](m);
|
wasm.dealloc = (m)=>wasm.exports[keyDealloc](m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reports info about compile-time options using
|
Reports info about compile-time options using
|
||||||
@ -679,7 +681,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
"SQLITE_" prefix. When it returns an object of all options,
|
"SQLITE_" prefix. When it returns an object of all options,
|
||||||
the prefix is elided.
|
the prefix is elided.
|
||||||
*/
|
*/
|
||||||
capi.wasm.compileOptionUsed = function f(optName){
|
wasm.compileOptionUsed = function f(optName){
|
||||||
if(!arguments.length){
|
if(!arguments.length){
|
||||||
if(f._result) return f._result;
|
if(f._result) return f._result;
|
||||||
else if(!f._opt){
|
else if(!f._opt){
|
||||||
@ -720,7 +722,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
is an array with 2+ elements:
|
is an array with 2+ elements:
|
||||||
|
|
||||||
[ "c-side name",
|
[ "c-side name",
|
||||||
"result type" (capi.wasm.xWrap() syntax),
|
"result type" (wasm.xWrap() syntax),
|
||||||
[arg types in xWrap() syntax]
|
[arg types in xWrap() syntax]
|
||||||
// ^^^ this needn't strictly be an array: it can be subsequent
|
// ^^^ this needn't strictly be an array: it can be subsequent
|
||||||
// elements instead: [x,y,z] is equivalent to x,y,z
|
// elements instead: [x,y,z] is equivalent to x,y,z
|
||||||
@ -730,7 +732,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
result/argument type strings gets plugged in at a later phase in
|
result/argument type strings gets plugged in at a later phase in
|
||||||
the API initialization process.
|
the API initialization process.
|
||||||
*/
|
*/
|
||||||
capi.wasm.bindingSignatures = [
|
wasm.bindingSignatures = [
|
||||||
// Please keep these sorted by function name!
|
// Please keep these sorted by function name!
|
||||||
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
|
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
|
||||||
["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
|
["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
|
||||||
@ -829,13 +831,13 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
["sqlite3_value_type", "int", "sqlite3_value*"],
|
["sqlite3_value_type", "int", "sqlite3_value*"],
|
||||||
["sqlite3_vfs_find", "*", "string"],
|
["sqlite3_vfs_find", "*", "string"],
|
||||||
["sqlite3_vfs_register", "int", "*", "int"]
|
["sqlite3_vfs_register", "int", "*", "int"]
|
||||||
]/*capi.wasm.bindingSignatures*/;
|
]/*wasm.bindingSignatures*/;
|
||||||
|
|
||||||
if(false && capi.wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
|
if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
|
||||||
/* ^^^ "the problem" is that this is an option feature and the
|
/* ^^^ "the problem" is that this is an option feature and the
|
||||||
build-time function-export list does not currently take
|
build-time function-export list does not currently take
|
||||||
optional features into account. */
|
optional features into account. */
|
||||||
capi.wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
|
wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -843,7 +845,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
the others because we need to conditionally bind them or apply
|
the others because we need to conditionally bind them or apply
|
||||||
dummy impls, depending on the capabilities of the environment.
|
dummy impls, depending on the capabilities of the environment.
|
||||||
*/
|
*/
|
||||||
capi.wasm.bindingSignatures.int64 = [
|
wasm.bindingSignatures.int64 = [
|
||||||
["sqlite3_bind_int64","int", ["sqlite3_stmt*", "int", "i64"]],
|
["sqlite3_bind_int64","int", ["sqlite3_stmt*", "int", "i64"]],
|
||||||
["sqlite3_changes64","i64", ["sqlite3*"]],
|
["sqlite3_changes64","i64", ["sqlite3*"]],
|
||||||
["sqlite3_column_int64","i64", ["sqlite3_stmt*", "int"]],
|
["sqlite3_column_int64","i64", ["sqlite3_stmt*", "int"]],
|
||||||
@ -859,18 +861,18 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
/**
|
/**
|
||||||
Functions which are intended solely for API-internal use by the
|
Functions which are intended solely for API-internal use by the
|
||||||
WASM components, not client code. These get installed into
|
WASM components, not client code. These get installed into
|
||||||
capi.wasm.
|
wasm.
|
||||||
|
|
||||||
TODO: get rid of sqlite3_wasm_vfs_unlink(). It is ill-conceived
|
TODO: get rid of sqlite3_wasm_vfs_unlink(). It is ill-conceived
|
||||||
and only rarely actually useful.
|
and only rarely actually useful.
|
||||||
*/
|
*/
|
||||||
capi.wasm.bindingSignatures.wasm = [
|
wasm.bindingSignatures.wasm = [
|
||||||
["sqlite3_wasm_vfs_unlink", "int", "string"]
|
["sqlite3_wasm_vfs_unlink", "int", "string"]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
sqlite3.capi.wasm.pstack (pseudo-stack) holds a special-case
|
sqlite3.wasm.pstack (pseudo-stack) holds a special-case
|
||||||
stack-style allocator intended only for use with _small_ data of
|
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
|
not more than (in total) a few kb in size, managed as if it were
|
||||||
stack-based.
|
stack-based.
|
||||||
@ -900,13 +902,13 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
memory lives in the WASM heap and can be used with routines such
|
memory lives in the WASM heap and can be used with routines such
|
||||||
as wasm.setMemValue() and any wasm.heap8u().slice().
|
as wasm.setMemValue() and any wasm.heap8u().slice().
|
||||||
*/
|
*/
|
||||||
capi.wasm.pstack = Object.assign(Object.create(null),{
|
wasm.pstack = Object.assign(Object.create(null),{
|
||||||
/**
|
/**
|
||||||
Sets the current ppstack position to the given pointer.
|
Sets the current ppstack position to the given pointer.
|
||||||
Results are undefined if the passed-in value did not come from
|
Results are undefined if the passed-in value did not come from
|
||||||
this.pointer.
|
this.pointer.
|
||||||
*/
|
*/
|
||||||
restore: capi.wasm.exports.sqlite3_wasm_pstack_restore,
|
restore: wasm.exports.sqlite3_wasm_pstack_restore,
|
||||||
/**
|
/**
|
||||||
Attempts to allocate the given number of bytes from the
|
Attempts to allocate the given number of bytes from the
|
||||||
pstack. On success, it zeroes out a block of memory of the
|
pstack. On success, it zeroes out a block of memory of the
|
||||||
@ -920,31 +922,89 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
heap.
|
heap.
|
||||||
*/
|
*/
|
||||||
alloc: (n)=>{
|
alloc: (n)=>{
|
||||||
return capi.wasm.exports.sqlite3_wasm_pstack_alloc(n)
|
return wasm.exports.sqlite3_wasm_pstack_alloc(n)
|
||||||
|| WasmAllocError.toss("Could not allocate",n,
|
|| WasmAllocError.toss("Could not allocate",n,
|
||||||
"bytes from the pstack.");
|
"bytes from the pstack.");
|
||||||
}
|
},
|
||||||
// More methods get added after the capi.wasm object is populated
|
|
||||||
// by WhWasmUtilInstaller.
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
sqlite3.capi.wasm.pstack.pointer resolves to the current pstack
|
Allocates n chunks, each sz bytes, as a single memory block and
|
||||||
position pointer. This value is intended _only_ to be passed to restore().
|
returns the addresses as an array of n element, each holding
|
||||||
|
the address of one chunk.
|
||||||
|
|
||||||
|
Throws a WasmAllocError if allocation fails.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
const [p1, p2, p3] = wasm.pstack.allocChunks(3,4);
|
||||||
|
```
|
||||||
*/
|
*/
|
||||||
Object.defineProperty(capi.wasm.pstack, 'pointer', {
|
allocChunks: (n,sz)=>{
|
||||||
|
const mem = wasm.pstack.alloc(n * sz);
|
||||||
|
const r
|
||||||
|
= [];
|
||||||
|
let i = 0, offset = 0;
|
||||||
|
for(; i < n; offset = (sz * ++i)){
|
||||||
|
rc.push(mem + offset);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
A convenience wrapper for allocChunks() which sizes each chunks
|
||||||
|
as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
|
||||||
|
safePtrSize is falsy).
|
||||||
|
|
||||||
|
How it returns its result differs depending on its first
|
||||||
|
argument: if it's 1, it returns a single pointer value. If it's
|
||||||
|
more than 1, it returns the same as allocChunks().
|
||||||
|
|
||||||
|
When a returned pointers will refer to a 64-bit value, e.g. a
|
||||||
|
double or int64, and that value must be written or fetched,
|
||||||
|
e.g. using wasm.setMemValue() or wasm.getMemValue(), 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 read neighboring memory.
|
||||||
|
|
||||||
|
However, when all pointers involved point to "small" data, it
|
||||||
|
is safe to pass a falsy value to save to memory.
|
||||||
|
*/
|
||||||
|
allocPtr: (n=1,safePtrSize=true)=>{
|
||||||
|
return 1===n
|
||||||
|
? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
|
||||||
|
: wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
|
||||||
|
}
|
||||||
|
})/*wasm.pstack*/;
|
||||||
|
Object.defineProperties(wasm.pstack, {
|
||||||
|
/**
|
||||||
|
sqlite3.wasm.pstack.pointer resolves to the current pstack
|
||||||
|
position pointer. This value is intended _only_ to be passed to
|
||||||
|
restore().
|
||||||
|
*/
|
||||||
|
pointer: {
|
||||||
configurable: false, iterable: true, writeable: false,
|
configurable: false, iterable: true, writeable: false,
|
||||||
get: capi.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 is unclear.
|
||||||
//set: capi.wasm.exports.sqlite3_wasm_pstack_restore
|
//set: wasm.exports.sqlite3_wasm_pstack_restore
|
||||||
});
|
},
|
||||||
/**
|
/**
|
||||||
sqlite3.capi.wasm.pstack.remaining resolves to the amount of
|
Resolves to the total number of bytes available in the pstack,
|
||||||
|
including any space which is currently allocated. This value is
|
||||||
|
a compile-time constant.
|
||||||
|
*/
|
||||||
|
quota: {
|
||||||
|
configurable: false, iterable: true, writeable: false,
|
||||||
|
get: wasm.exports.sqlite3_wasm_pstack_quota
|
||||||
|
}
|
||||||
|
})/*wasm.pstack properties*/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
sqlite3.wasm.pstack.remaining resolves to the amount of
|
||||||
space remaining in the pstack.
|
space remaining in the pstack.
|
||||||
*/
|
*/
|
||||||
Object.defineProperty(capi.wasm.pstack, 'remaining', {
|
Object.defineProperty(wasm.pstack, 'remaining', {
|
||||||
configurable: false, iterable: true, writeable: false,
|
configurable: false, iterable: true, writeable: false,
|
||||||
get: capi.wasm.exports.sqlite3_wasm_pstack_remaining
|
get: wasm.exports.sqlite3_wasm_pstack_remaining
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -994,7 +1054,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
return __persistentDir = "";
|
return __persistentDir = "";
|
||||||
}
|
}
|
||||||
try{
|
try{
|
||||||
if(pdir && 0===capi.wasm.xCallWrapped(
|
if(pdir && 0===wasm.xCallWrapped(
|
||||||
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
|
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
|
||||||
)){
|
)){
|
||||||
return __persistentDir = pdir;
|
return __persistentDir = pdir;
|
||||||
@ -1024,10 +1084,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// This bit is highly arguable and is incompatible with the fiddle shell.
|
// This bit is highly arguable and is incompatible with the fiddle shell.
|
||||||
if(false && 0===capi.wasm.exports.sqlite3_vfs_find(0)){
|
if(false && 0===wasm.exports.sqlite3_vfs_find(0)){
|
||||||
/* Assume that sqlite3_initialize() has not yet been called.
|
/* Assume that sqlite3_initialize() has not yet been called.
|
||||||
This will be the case in an SQLITE_OS_KV build. */
|
This will be the case in an SQLITE_OS_KV build. */
|
||||||
capi.wasm.exports.sqlite3_initialize();
|
wasm.exports.sqlite3_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1058,15 +1118,15 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
else if(!pDb){
|
else if(!pDb){
|
||||||
return capi.sqlite3_vfs_find(0)===pK ? pK : false;
|
return capi.sqlite3_vfs_find(0)===pK ? pK : false;
|
||||||
}
|
}
|
||||||
const ppVfs = capi.wasm.allocPtr();
|
const ppVfs = wasm.allocPtr();
|
||||||
try{
|
try{
|
||||||
return (
|
return (
|
||||||
(0===capi.sqlite3_file_control(
|
(0===capi.sqlite3_file_control(
|
||||||
pDb, dbName, capi.SQLITE_FCNTL_VFS_POINTER, ppVfs
|
pDb, dbName, capi.SQLITE_FCNTL_VFS_POINTER, ppVfs
|
||||||
)) && (capi.wasm.getPtrValue(ppVfs) === pK)
|
)) && (wasm.getPtrValue(ppVfs) === pK)
|
||||||
) ? pK : false;
|
) ? pK : false;
|
||||||
}finally{
|
}finally{
|
||||||
capi.wasm.dealloc(ppVfs);
|
wasm.dealloc(ppVfs);
|
||||||
}
|
}
|
||||||
}catch(e){
|
}catch(e){
|
||||||
/* Ignore - probably bad args to a wasm-bound function. */
|
/* Ignore - probably bad args to a wasm-bound function. */
|
||||||
@ -1083,7 +1143,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
let pVfs = capi.sqlite3_vfs_find(0);
|
let pVfs = capi.sqlite3_vfs_find(0);
|
||||||
while(pVfs){
|
while(pVfs){
|
||||||
const oVfs = new capi.sqlite3_vfs(pVfs);
|
const oVfs = new capi.sqlite3_vfs(pVfs);
|
||||||
rc.push(capi.wasm.cstringToJs(oVfs.$zName));
|
rc.push(wasm.cstringToJs(oVfs.$zName));
|
||||||
pVfs = oVfs.$pNext;
|
pVfs = oVfs.$pNext;
|
||||||
oVfs.dispose();
|
oVfs.dispose();
|
||||||
}
|
}
|
||||||
@ -1097,7 +1157,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
*/
|
*/
|
||||||
capi.sqlite3_web_db_export = function(pDb){
|
capi.sqlite3_web_db_export = function(pDb){
|
||||||
if(!pDb) toss('Invalid sqlite3* argument.');
|
if(!pDb) toss('Invalid sqlite3* argument.');
|
||||||
const wasm = capi.wasm;
|
const wasm = wasm;
|
||||||
if(!wasm.bigIntEnabled) toss('BigInt64 support is not enabled.');
|
if(!wasm.bigIntEnabled) toss('BigInt64 support is not enabled.');
|
||||||
const stack = wasm.pstack.pointer;
|
const stack = wasm.pstack.pointer;
|
||||||
let pOut;
|
let pOut;
|
||||||
@ -1278,7 +1338,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
|
|
||||||
Note that the order of insertion into this array is significant for
|
Note that the order of insertion into this array is significant for
|
||||||
some pieces. e.g. sqlite3.capi.wasm cannot be fully utilized until
|
some pieces. e.g. sqlite3.capi.wasm cannot be fully utilized until
|
||||||
the whwasmutil.js part is plugged in.
|
the whwasmutil.js part is plugged in via sqlite3-api-glue.js.
|
||||||
*/
|
*/
|
||||||
self.sqlite3ApiBootstrap.initializers = [];
|
self.sqlite3ApiBootstrap.initializers = [];
|
||||||
/**
|
/**
|
||||||
@ -1290,7 +1350,10 @@ self.sqlite3ApiBootstrap.initializers = [];
|
|||||||
Counterpart of self.sqlite3ApiBootstrap.initializers, specifically
|
Counterpart of self.sqlite3ApiBootstrap.initializers, specifically
|
||||||
for initializers which are asynchronous. All functions in this list
|
for initializers which are asynchronous. All functions in this list
|
||||||
take the sqlite3 object as their argument and MUST return a
|
take the sqlite3 object as their argument and MUST return a
|
||||||
Promise. Both the resolved value and rejection cases are ignored.
|
Promise. The resolved value and ignored and rejection will kill the
|
||||||
|
asyncPostInit() process but will be otherwise ignored because the
|
||||||
|
post-synchronous-init async initialization parts are (as of this
|
||||||
|
writing) all optional.
|
||||||
|
|
||||||
This list is not processed until the client calls
|
This list is not processed until the client calls
|
||||||
sqlite3.asyncPostInit(). This means, for example, that intializers
|
sqlite3.asyncPostInit(). This means, for example, that intializers
|
||||||
|
@ -135,13 +135,13 @@ WASM_KEEP void * sqlite3_wasm_stack_begin(void){
|
|||||||
extern void __data_end;
|
extern void __data_end;
|
||||||
return &__data_end;
|
return &__data_end;
|
||||||
}
|
}
|
||||||
static void * sq3StackPtr = 0;
|
static void * pWasmStackPtr = 0;
|
||||||
WASM_KEEP void * sqlite3_wasm_stack_ptr(void){
|
WASM_KEEP void * sqlite3_wasm_stack_ptr(void){
|
||||||
if(!sq3StackPtr) sq3StackPtr = sqlite3_wasm_stack_end();
|
if(!pWasmStackPtr) pWasmStackPtr = sqlite3_wasm_stack_end();
|
||||||
return sq3StackPtr;
|
return pWasmStackPtr;
|
||||||
}
|
}
|
||||||
WASM_KEEP void sqlite3_wasm_stack_restore(void * p){
|
WASM_KEEP void sqlite3_wasm_stack_restore(void * p){
|
||||||
sq3StackPtr = p;
|
pWasmStackPtr = p;
|
||||||
}
|
}
|
||||||
WASM_KEEP void * sqlite3_wasm_stack_alloc(int n){
|
WASM_KEEP void * sqlite3_wasm_stack_alloc(int n){
|
||||||
if(n<=0) return 0;
|
if(n<=0) return 0;
|
||||||
@ -149,7 +149,7 @@ WASM_KEEP void * sqlite3_wasm_stack_alloc(int n){
|
|||||||
unsigned char * const p = (unsigned char *)sqlite3_wasm_stack_ptr();
|
unsigned char * const p = (unsigned char *)sqlite3_wasm_stack_ptr();
|
||||||
unsigned const char * const b = (unsigned const char *)sqlite3_wasm_stack_begin();
|
unsigned const char * const b = (unsigned const char *)sqlite3_wasm_stack_begin();
|
||||||
if(b + n >= p || b + n < b/*overflow*/) return 0;
|
if(b + n >= p || b + n < b/*overflow*/) return 0;
|
||||||
return sq3StackPtr = p - n;
|
return pWasmStackPtr = p - n;
|
||||||
}
|
}
|
||||||
#endif /* stack allocator experiment */
|
#endif /* stack allocator experiment */
|
||||||
|
|
||||||
@ -205,10 +205,9 @@ WASM_KEEP void * sqlite3_wasm_pstack_alloc(int n){
|
|||||||
if( n<=0 ) return 0;
|
if( n<=0 ) return 0;
|
||||||
//if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */;
|
//if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */;
|
||||||
n = (n + 7) & ~7 /* align to 8-byte boundary */;
|
n = (n + 7) & ~7 /* align to 8-byte boundary */;
|
||||||
unsigned char * const p = PStack.pPos;
|
if( PStack.pBegin + n > PStack.pPos /*not enough space left*/
|
||||||
unsigned const char * const b = PStack.pBegin;
|
|| PStack.pBegin + n <= PStack.pBegin /*overflow*/ ) return 0;
|
||||||
if( b + n > p || b + n <= b/*overflow*/ ) return 0;
|
memset((PStack.pPos = PStack.pPos - n), 0, (unsigned int)n);
|
||||||
memset((PStack.pPos = p - n), 0, (unsigned int)n);
|
|
||||||
return PStack.pPos;
|
return PStack.pPos;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -221,6 +220,14 @@ WASM_KEEP int sqlite3_wasm_pstack_remaining(void){
|
|||||||
return (int)(PStack.pPos - PStack.pBegin);
|
return (int)(PStack.pPos - PStack.pBegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the total number of bytes available in the pstack, including
|
||||||
|
** any space which is currently allocated. This value is a
|
||||||
|
** compile-time constant.
|
||||||
|
*/
|
||||||
|
WASM_KEEP int sqlite3_wasm_pstack_quota(void){
|
||||||
|
return (int)(PStack.pEnd - PStack.pBegin);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This function is NOT part of the sqlite3 public API. It is strictly
|
** This function is NOT part of the sqlite3 public API. It is strictly
|
||||||
@ -254,26 +261,26 @@ int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){
|
|||||||
** variadic macros.
|
** variadic macros.
|
||||||
**
|
**
|
||||||
** Returns a string containing a JSON-format "enum" of C-level
|
** Returns a string containing a JSON-format "enum" of C-level
|
||||||
** constants intended to be imported into the JS environment. The JSON
|
** constants and struct-related metadata intended to be imported into
|
||||||
** is initialized the first time this function is called and that
|
** the JS environment. The JSON is initialized the first time this
|
||||||
** result is reused for all future calls.
|
** function is called and that result is reused for all future calls.
|
||||||
**
|
**
|
||||||
** If this function returns NULL then it means that the internal
|
** If this function returns NULL then it means that the internal
|
||||||
** buffer is not large enough for the generated JSON. In debug builds
|
** buffer is not large enough for the generated JSON and needs to be
|
||||||
** that will trigger an assert().
|
** increased. In debug builds that will trigger an assert().
|
||||||
*/
|
*/
|
||||||
WASM_KEEP
|
WASM_KEEP
|
||||||
const char * sqlite3_wasm_enum_json(void){
|
const char * sqlite3_wasm_enum_json(void){
|
||||||
static char azBuffer[1024 * 12] = {0} /* where the JSON goes */;
|
static char aBuffer[1024 * 12] = {0} /* where the JSON goes */;
|
||||||
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 = &azBuffer[1] /* skip first byte for now to help protect
|
char * zPos = &aBuffer[1] /* skip first byte for now to help protect
|
||||||
** against a small race condition */;
|
** against a small race condition */;
|
||||||
char const * const zEnd = &azBuffer[0] + sizeof(azBuffer) /* one-past-the-end */;
|
char const * const zEnd = &aBuffer[0] + sizeof(aBuffer) /* one-past-the-end */;
|
||||||
if(azBuffer[0]) return azBuffer;
|
if(aBuffer[0]) return aBuffer;
|
||||||
/* Leave azBuffer[0] at 0 until the end to help guard against a tiny
|
/* Leave aBuffer[0] at 0 until the end to help guard against a tiny
|
||||||
** race condition. If this is called twice concurrently, they might
|
** race condition. If this is called twice concurrently, they might
|
||||||
** end up both writing to azBuffer, but they'll both write the same
|
** end up both writing to aBuffer, but they'll both write the same
|
||||||
** thing, so that's okay. If we set byte 0 up front then the 2nd
|
** thing, so that's okay. If we set byte 0 up front then the 2nd
|
||||||
** instance might return and use the string before the 1st instance
|
** instance might return and use the string before the 1st instance
|
||||||
** is done filling it. */
|
** is done filling it. */
|
||||||
@ -680,8 +687,8 @@ const char * sqlite3_wasm_enum_json(void){
|
|||||||
|
|
||||||
out("}"/*top-level object*/);
|
out("}"/*top-level object*/);
|
||||||
*zPos = 0;
|
*zPos = 0;
|
||||||
azBuffer[0] = '{'/*end of the race-condition workaround*/;
|
aBuffer[0] = '{'/*end of the race-condition workaround*/;
|
||||||
return azBuffer;
|
return aBuffer;
|
||||||
#undef StructBinder
|
#undef StructBinder
|
||||||
#undef StructBinder_
|
#undef StructBinder_
|
||||||
#undef StructBinder__
|
#undef StructBinder__
|
||||||
|
@ -1033,9 +1033,10 @@
|
|||||||
const stack = P.pointer;
|
const stack = P.pointer;
|
||||||
T.assert(0===stack % 8 /* must be 8-byte aligned */);
|
T.assert(0===stack % 8 /* must be 8-byte aligned */);
|
||||||
try{
|
try{
|
||||||
const quota = P.remaining;
|
const remaining = P.remaining;
|
||||||
log("pstack quota",quota);
|
log("pstack quota, remaining",P.quota,remaining);
|
||||||
T.assert(quota >= 4096)
|
T.assert(P.quota >= 4096)
|
||||||
|
.assert(remaining === P.quota)
|
||||||
.mustThrowMatching(()=>P.alloc(0), isAllocErr)
|
.mustThrowMatching(()=>P.alloc(0), isAllocErr)
|
||||||
.mustThrowMatching(()=>P.alloc(-1), isAllocErr);
|
.mustThrowMatching(()=>P.alloc(-1), isAllocErr);
|
||||||
let p1 = P.alloc(12);
|
let p1 = P.alloc(12);
|
||||||
@ -1043,12 +1044,12 @@
|
|||||||
.assert(P.pointer === p1);
|
.assert(P.pointer === p1);
|
||||||
let p2 = P.alloc(7);
|
let p2 = P.alloc(7);
|
||||||
T.assert(p2 === p1-8/*8-byte aligned, stack grows downwards*/)
|
T.assert(p2 === p1-8/*8-byte aligned, stack grows downwards*/)
|
||||||
.mustThrowMatching(()=>P.alloc(quota), isAllocErr)
|
.mustThrowMatching(()=>P.alloc(remaining), isAllocErr)
|
||||||
.assert(24 === stack - p2)
|
.assert(24 === stack - p2)
|
||||||
.assert(P.pointer === p2);
|
.assert(P.pointer === p2);
|
||||||
let n = quota - (stack - p2);
|
let n = remaining - (stack - p2);
|
||||||
let p3 = P.alloc(n);
|
let p3 = P.alloc(n);
|
||||||
T.assert(p3 === stack-quota)
|
T.assert(p3 === stack-remaining)
|
||||||
.mustThrowMatching(()=>P.alloc(1), isAllocErr);
|
.mustThrowMatching(()=>P.alloc(1), isAllocErr);
|
||||||
}finally{
|
}finally{
|
||||||
P.restore(stack);
|
P.restore(stack);
|
||||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\sa\stest/debug\smechanism\sto\sshut\sdown\sthe\sOPFS\sasync\slistener\sso\sthat\sit\scan\sbe\sinspected\s(it\snormally\scan't\sbe\sbecause\sits\stight\sevent-listening\sloop\sties\sup\sthe\sthread)\sand\sthen\srestarted.
|
C Minor\scleanups\sand\sadditions\sin\ssqlite3.capi.wasm.pstack.
|
||||||
D 2022-10-04T00:54:00.533
|
D 2022-10-04T01:11:10.003
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -485,13 +485,13 @@ F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba814
|
|||||||
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
|
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
|
||||||
F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b
|
F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js 5d22d1d3818ecacb23bfa223d5970cd0617d8cdbb48c8bc4bbd463f05b021a99
|
F ext/wasm/api/sqlite3-api-cleanup.js 5d22d1d3818ecacb23bfa223d5970cd0617d8cdbb48c8bc4bbd463f05b021a99
|
||||||
F ext/wasm/api/sqlite3-api-glue.js 24a283a49759914f2433b3118865145efbb2f67f52643e445065e02ccecc081b
|
F ext/wasm/api/sqlite3-api-glue.js a5a1bd620e2e2c26b6e843cf439548b35c5bb5ed21b24b89a412e0b0a8592c42
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js ac1e08d36bdfb5aa0a2d75b7d4c892fd51819d34c932370c3282810672bcc086
|
F ext/wasm/api/sqlite3-api-oo1.js ac1e08d36bdfb5aa0a2d75b7d4c892fd51819d34c932370c3282810672bcc086
|
||||||
F ext/wasm/api/sqlite3-api-opfs.js d82870cffef9eef6511c650759c3798b59f10c8338587789abd84be2d9d845c3
|
F ext/wasm/api/sqlite3-api-opfs.js d82870cffef9eef6511c650759c3798b59f10c8338587789abd84be2d9d845c3
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js 61f28bf7a51479c7b401e2da636b2a0710de77d86f68961445d572a3761dd170
|
F ext/wasm/api/sqlite3-api-prologue.js 8f7e46105f9bea362894725531d6f8aa52981f5ef3f1679dd8caa7c85c135566
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js 7f4f46cb6b512a48572d7567233896e6a9c46570c44bdc3d13419730c7c221c8
|
F ext/wasm/api/sqlite3-api-worker1.js 7f4f46cb6b512a48572d7567233896e6a9c46570c44bdc3d13419730c7c221c8
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||||
F ext/wasm/api/sqlite3-wasm.c 1ed1356752c02a991b2d16c32e3e5c138a03526bb60182f2a751ec5372ecba12
|
F ext/wasm/api/sqlite3-wasm.c 0c8cb242b80b8de27b74f05ed781f427958e04c9339c4720f30c3a7e78ee6242
|
||||||
F ext/wasm/batch-runner.html cf1a410c92bad50fcec2ddc71390b4e9df63a6ea1bef12a5163a66a0af4d78d9
|
F ext/wasm/batch-runner.html cf1a410c92bad50fcec2ddc71390b4e9df63a6ea1bef12a5163a66a0af4d78d9
|
||||||
F ext/wasm/batch-runner.js 5bae81684728b6be157d1f92b39824153f0fd019345b39f2ab8930f7ee2a57d8
|
F ext/wasm/batch-runner.js 5bae81684728b6be157d1f92b39824153f0fd019345b39f2ab8930f7ee2a57d8
|
||||||
F ext/wasm/common/SqliteTestUtil.js 647bf014bd30bdd870a7e9001e251d12fc1c9ec9ce176a1004b838a4b33c5c05
|
F ext/wasm/common/SqliteTestUtil.js 647bf014bd30bdd870a7e9001e251d12fc1c9ec9ce176a1004b838a4b33c5c05
|
||||||
@ -530,7 +530,7 @@ F ext/wasm/test-opfs-vfs.js 0115d56f3f2a6475040dffe75a6851a353b1690708795944cf0f
|
|||||||
F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
|
F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
|
||||||
F ext/wasm/testing-worker1-promiser.js bd788e33c1807e0a6dda9c9a9d784bd3350ca49c9dd8ae2cc8719b506b6e013e
|
F ext/wasm/testing-worker1-promiser.js bd788e33c1807e0a6dda9c9a9d784bd3350ca49c9dd8ae2cc8719b506b6e013e
|
||||||
F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d7669fb17fcae
|
F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d7669fb17fcae
|
||||||
F ext/wasm/testing1.js 0f87073086eff3a152f013874f1c9a710e63d2e069f90dfeb8333ffe82476d04
|
F ext/wasm/testing1.js 15fc3dca6b2fc22c1458cca2cc2c484281dfc91f01c048ad4e38d5d3924ea961
|
||||||
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
||||||
F ext/wasm/testing2.js 88f40ef3cd8201bdadd120a711c36bbf0ce56cc0eab1d5e7debb71fed7822494
|
F ext/wasm/testing2.js 88f40ef3cd8201bdadd120a711c36bbf0ce56cc0eab1d5e7debb71fed7822494
|
||||||
F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f
|
F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f
|
||||||
@ -2029,8 +2029,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 72a9e589cc318ec50941739e2edf2c0636284b316c3bf87b71fd363b37619da3
|
P 7d0bcff4e9b899cd25b393b9f0a02c5dcee2e229f0a0fa01719c7dcd7dcbe7c1
|
||||||
R b598562b6232b1a22591d878d099e519
|
R 7320921a42fda536d083483db8ee576c
|
||||||
U stephan
|
U stephan
|
||||||
Z 962cbcc757fdf40c47c3a7056efb3d7c
|
Z 3678381f6d3f10154c88d71945cdf539
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
7d0bcff4e9b899cd25b393b9f0a02c5dcee2e229f0a0fa01719c7dcd7dcbe7c1
|
97bd670d3859bd3f2e62c15065b238b85ef614f26479e56a14be42c5784aedf4
|
Reference in New Issue
Block a user