}/*wasm*/
}/*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
TypedArray, and returns the pointer to that memory. The
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
this is used, if srcTypedArray.byteLength is 0, it
Int8Array types and will throw if srcTypedArray is of
any other type.
*/
- capi.wasm.allocFromTypedArray = function(srcTypedArray){
+ wasm.allocFromTypedArray = function(srcTypedArray){
affirmBindableTypedArray(srcTypedArray);
- const pRet = capi.wasm.alloc(srcTypedArray.byteLength || 1);
- capi.wasm.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
+ const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
+ wasm.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
return pRet;
};
const keyAlloc = config.allocExportName || 'malloc',
keyDealloc = config.deallocExportName || 'free';
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.");
}
- capi.wasm.alloc = function(n){
- const m = capi.wasm.exports[keyAlloc](n);
+ wasm.alloc = function(n){
+ const m = wasm.exports[keyAlloc](n);
if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
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
"SQLITE_" prefix. When it returns an object of all options,
the prefix is elided.
*/
- capi.wasm.compileOptionUsed = function f(optName){
+ wasm.compileOptionUsed = function f(optName){
if(!arguments.length){
if(f._result) return f._result;
else if(!f._opt){
is an array with 2+ elements:
[ "c-side name",
- "result type" (capi.wasm.xWrap() syntax),
+ "result type" (wasm.xWrap() syntax),
[arg types in xWrap() syntax]
// ^^^ this needn't strictly be an array: it can be subsequent
// elements instead: [x,y,z] is equivalent to x,y,z
result/argument type strings gets plugged in at a later phase in
the API initialization process.
*/
- capi.wasm.bindingSignatures = [
+ wasm.bindingSignatures = [
// Please keep these sorted by function name!
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
["sqlite3_value_type", "int", "sqlite3_value*"],
["sqlite3_vfs_find", "*", "string"],
["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
build-time function-export list does not currently take
optional features into account. */
- capi.wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
+ wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
}
/**
the others because we need to conditionally bind them or apply
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_changes64","i64", ["sqlite3*"]],
["sqlite3_column_int64","i64", ["sqlite3_stmt*", "int"]],
/**
Functions which are intended solely for API-internal use by the
WASM components, not client code. These get installed into
- capi.wasm.
+ wasm.
TODO: get rid of sqlite3_wasm_vfs_unlink(). It is ill-conceived
and only rarely actually useful.
*/
- capi.wasm.bindingSignatures.wasm = [
+ wasm.bindingSignatures.wasm = [
["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
not more than (in total) a few kb in size, managed as if it were
stack-based.
memory lives in the WASM heap and can be used with routines such
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.
Results are undefined if the passed-in value did not come from
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
pstack. On success, it zeroes out a block of memory of the
heap.
*/
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,
"bytes from the pstack.");
+ },
+ /**
+ 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);
+ ```
+ */
+ 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);
}
- // More methods get added after the capi.wasm object is populated
- // by WhWasmUtilInstaller.
- });
- /**
- sqlite3.capi.wasm.pstack.pointer resolves to the current pstack
- position pointer. This value is intended _only_ to be passed to restore().
- */
- Object.defineProperty(capi.wasm.pstack, 'pointer', {
- configurable: false, iterable: true, writeable: false,
- get: capi.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.
- //set: capi.wasm.exports.sqlite3_wasm_pstack_restore
- });
+ })/*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,
+ 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.
+ //set: wasm.exports.sqlite3_wasm_pstack_restore
+ },
+ /**
+ 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.capi.wasm.pstack.remaining resolves to the amount of
+ sqlite3.wasm.pstack.remaining resolves to the amount of
space remaining in the pstack.
*/
- Object.defineProperty(capi.wasm.pstack, 'remaining', {
+ Object.defineProperty(wasm.pstack, 'remaining', {
configurable: false, iterable: true, writeable: false,
- get: capi.wasm.exports.sqlite3_wasm_pstack_remaining
+ get: wasm.exports.sqlite3_wasm_pstack_remaining
});
/**
return __persistentDir = "";
}
try{
- if(pdir && 0===capi.wasm.xCallWrapped(
+ if(pdir && 0===wasm.xCallWrapped(
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
)){
return __persistentDir = pdir;
};
// 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.
This will be the case in an SQLITE_OS_KV build. */
- capi.wasm.exports.sqlite3_initialize();
+ wasm.exports.sqlite3_initialize();
}
/**
else if(!pDb){
return capi.sqlite3_vfs_find(0)===pK ? pK : false;
}
- const ppVfs = capi.wasm.allocPtr();
+ const ppVfs = wasm.allocPtr();
try{
return (
(0===capi.sqlite3_file_control(
pDb, dbName, capi.SQLITE_FCNTL_VFS_POINTER, ppVfs
- )) && (capi.wasm.getPtrValue(ppVfs) === pK)
+ )) && (wasm.getPtrValue(ppVfs) === pK)
) ? pK : false;
}finally{
- capi.wasm.dealloc(ppVfs);
+ wasm.dealloc(ppVfs);
}
}catch(e){
/* Ignore - probably bad args to a wasm-bound function. */
let pVfs = capi.sqlite3_vfs_find(0);
while(pVfs){
const oVfs = new capi.sqlite3_vfs(pVfs);
- rc.push(capi.wasm.cstringToJs(oVfs.$zName));
+ rc.push(wasm.cstringToJs(oVfs.$zName));
pVfs = oVfs.$pNext;
oVfs.dispose();
}
*/
capi.sqlite3_web_db_export = function(pDb){
if(!pDb) toss('Invalid sqlite3* argument.');
- const wasm = capi.wasm;
+ const wasm = wasm;
if(!wasm.bigIntEnabled) toss('BigInt64 support is not enabled.');
const stack = wasm.pstack.pointer;
let pOut;
Note that the order of insertion into this array is significant for
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 = [];
/**
Counterpart of self.sqlite3ApiBootstrap.initializers, specifically
for initializers which are asynchronous. All functions in this list
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
sqlite3.asyncPostInit(). This means, for example, that intializers
added to self.sqlite3ApiBootstrap.initializers may push entries to
- this list.
+ this list.
*/
self.sqlite3ApiBootstrap.initializersAsync = [];
/**
extern void __data_end;
return &__data_end;
}
-static void * sq3StackPtr = 0;
+static void * pWasmStackPtr = 0;
WASM_KEEP void * sqlite3_wasm_stack_ptr(void){
- if(!sq3StackPtr) sq3StackPtr = sqlite3_wasm_stack_end();
- return sq3StackPtr;
+ if(!pWasmStackPtr) pWasmStackPtr = sqlite3_wasm_stack_end();
+ return pWasmStackPtr;
}
WASM_KEEP void sqlite3_wasm_stack_restore(void * p){
- sq3StackPtr = p;
+ pWasmStackPtr = p;
}
WASM_KEEP void * sqlite3_wasm_stack_alloc(int n){
if(n<=0) return 0;
unsigned char * const p = (unsigned char *)sqlite3_wasm_stack_ptr();
unsigned const char * const b = (unsigned const char *)sqlite3_wasm_stack_begin();
if(b + n >= p || b + n < b/*overflow*/) return 0;
- return sq3StackPtr = p - n;
+ return pWasmStackPtr = p - n;
}
#endif /* stack allocator experiment */
if( n<=0 ) return 0;
//if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */;
n = (n + 7) & ~7 /* align to 8-byte boundary */;
- unsigned char * const p = PStack.pPos;
- unsigned const char * const b = PStack.pBegin;
- if( b + n > p || b + n <= b/*overflow*/ ) return 0;
- memset((PStack.pPos = p - n), 0, (unsigned int)n);
+ if( PStack.pBegin + n > PStack.pPos /*not enough space left*/
+ || PStack.pBegin + n <= PStack.pBegin /*overflow*/ ) return 0;
+ memset((PStack.pPos = PStack.pPos - n), 0, (unsigned int)n);
return PStack.pPos;
}
/*
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
** variadic macros.
**
** Returns a string containing a JSON-format "enum" of C-level
-** constants intended to be imported into the JS environment. The JSON
-** is initialized the first time this function is called and that
-** result is reused for all future calls.
+** constants and struct-related metadata intended to be imported into
+** the JS environment. The JSON is initialized the first time this
+** function is called and that result is reused for all future calls.
**
** If this function returns NULL then it means that the internal
-** buffer is not large enough for the generated JSON. In debug builds
-** that will trigger an assert().
+** buffer is not large enough for the generated JSON and needs to be
+** increased. In debug builds that will trigger an assert().
*/
WASM_KEEP
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
/* 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 */;
- char const * const zEnd = &azBuffer[0] + sizeof(azBuffer) /* one-past-the-end */;
- if(azBuffer[0]) return azBuffer;
- /* Leave azBuffer[0] at 0 until the end to help guard against a tiny
+ char const * const zEnd = &aBuffer[0] + sizeof(aBuffer) /* one-past-the-end */;
+ if(aBuffer[0]) return aBuffer;
+ /* Leave aBuffer[0] at 0 until the end to help guard against a tiny
** 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
** instance might return and use the string before the 1st instance
** is done filling it. */
out("}"/*top-level object*/);
*zPos = 0;
- azBuffer[0] = '{'/*end of the race-condition workaround*/;
- return azBuffer;
+ aBuffer[0] = '{'/*end of the race-condition workaround*/;
+ return aBuffer;
#undef StructBinder
#undef StructBinder_
#undef StructBinder__
-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.
-D 2022-10-04T00:54:00.533
+C Minor\scleanups\sand\sadditions\sin\ssqlite3.capi.wasm.pstack.
+D 2022-10-04T01:11:10.003
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b
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-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-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.js 5bae81684728b6be157d1f92b39824153f0fd019345b39f2ab8930f7ee2a57d8
F ext/wasm/common/SqliteTestUtil.js 647bf014bd30bdd870a7e9001e251d12fc1c9ec9ce176a1004b838a4b33c5c05
F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
F ext/wasm/testing-worker1-promiser.js bd788e33c1807e0a6dda9c9a9d784bd3350ca49c9dd8ae2cc8719b506b6e013e
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.js 88f40ef3cd8201bdadd120a711c36bbf0ce56cc0eab1d5e7debb71fed7822494
F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 72a9e589cc318ec50941739e2edf2c0636284b316c3bf87b71fd363b37619da3
-R b598562b6232b1a22591d878d099e519
+P 7d0bcff4e9b899cd25b393b9f0a02c5dcee2e229f0a0fa01719c7dcd7dcbe7c1
+R 7320921a42fda536d083483db8ee576c
U stephan
-Z 962cbcc757fdf40c47c3a7056efb3d7c
+Z 3678381f6d3f10154c88d71945cdf539
# Remove this line to create a well-formed Fossil manifest.