return (v && v.constructor && isInt32(v.constructor.BYTES_PER_ELEMENT)) ? v : false;
};
+
+ /** Internal helper to use in operations which need to distinguish
+ between TypedArrays which are backed by a SharedArrayBuffer
+ from those which are not. */
+ const __SAB = ('undefined'===typeof SharedArrayBuffer)
+ ? function(){} : SharedArrayBuffer;
+ /** Returns true if the given TypedArray object is backed by a
+ SharedArrayBuffer, else false. */
+ const isSharedTypedArray = (aTypedArray)=>(aTypedArray.buffer instanceof __SAB);
+
+ /**
+ Returns either aTypedArray.slice(begin,end) (if
+ aTypedArray.buffer is a SharedArrayBuffer) or
+ aTypedArray.subarray(begin,end) (if it's not).
+
+ This distinction is important for APIs which don't like to
+ work on SABs, e.g. TextDecoder, and possibly for our
+ own APIs which work on memory ranges which "might" be
+ modified by other threads while it's working.
+ */
+ const typedArrayPart = (aTypedArray, begin, end)=>{
+ return isSharedTypedArray(aTypedArray)
+ ? aTypedArray.slice(begin, end)
+ : aTypedArray.subarray(begin, end);
+ };
+
/**
Returns true if v appears to be one of our bind()-able
TypedArray types: Uint8Array or Int8Array. Support for
const utf8Decoder = new TextDecoder('utf-8');
- /** Internal helper to use in operations which need to distinguish
- between SharedArrayBuffer heap memory and non-shared heap. */
- const __SAB = ('undefined'===typeof SharedArrayBuffer)
- ? function(){} : SharedArrayBuffer;
- const typedArrayToString = function(arrayBuffer, begin, end){
- return utf8Decoder.decode(
- (arrayBuffer.buffer instanceof __SAB)
- ? arrayBuffer.slice(begin, end)
- : arrayBuffer.subarray(begin, end)
- );
+ /**
+ Uses TextDecoder to decode the given half-open range of the
+ given TypedArray to a string. This differs from a simple
+ call to TextDecoder in that it accounts for whether the
+ first argument is based by a SharedArrayBuffer or not,
+ and can work more efficiently if it's not (TextDecoder
+ refuses to act upon an SAB).
+ */
+ const typedArrayToString = function(typedArray, begin, end){
+ return utf8Decoder.decode(typedArrayPart(typedArray, begin,end));
};
/**
If the callback is a function, then for the duration of the
sqlite3_exec() call, it installs a WASM-bound function which
- acts as a proxy for the given callback. That proxy will
- also perform a conversion of the callback's arguments from
+ acts as a proxy for the given callback. That proxy will also
+ perform a conversion of the callback's arguments from
`(char**)` to JS arrays of strings. However, for API
- consistency's sake it will still honor the C-level
- callback parameter order and will call it like:
+ consistency's sake it will still honor the C-level callback
+ parameter order and will call it like:
`callback(pVoid, colCount, listOfValues, listOfColNames)`
*/
sqlite3_exec: (pDb, sql, callback, pVoid, pErrMsg)=>{}/*installed later*/,
+ /**
+ If passed a single argument which appears to be a byte-oriented
+ TypedArray (Int8Array or Uint8Array), this function treats that
+ TypedArray as an output target, fetches `theArray.byteLength`
+ bytes of randomness, and populates the whole array with it. As
+ a special case, if the array's length is 0, this function
+ behaves as if it were passed (0,0). When called this way, it
+ returns its argument, else it returns the `undefined` value.
+
+ If called with any other arguments, they are passed on as-is
+ to the C API. Results are undefined if passed any incompatible
+ values.
+ */
+ sqlite3_randomness: (n, outPtr)=>{/*installed later*/},
+
/**
Various internal-use utilities are added here as needed. They
are bound to an object only so that we have access to them in
the differently-scoped steps of the API bootstrapping
process. At the end of the API setup process, this object gets
- removed.
+ removed. These are NOT part of the public API.
*/
util:{
affirmBindableTypedArray, flexibleString,
isBindableTypedArray,
isInt32, isSQLableTypedArray, isTypedArray,
typedArrayToString,
- isUIThread: ()=>'undefined'===typeof WorkerGlobalScope
+ isUIThread: ()=>'undefined'===typeof WorkerGlobalScope,
+ isSharedTypedArray,
+ typedArrayPart
},
/**
}/*wasm*/
}/*capi*/;
- const wasm = capi.wasm;
+ const wasm = capi.wasm, util = capi.util;
/**
wasm.alloc()'s srcTypedArray.byteLength bytes,
// Please keep these sorted by function name!
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
- /* We should arguably write a custom wrapper which knows how
- to handle Blob, TypedArrays, and JS strings. */
+ /* TODO: we should arguably write a custom wrapper which knows
+ how to handle Blob, TypedArrays, and JS strings. */
],
["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"],
["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"],
["sqlite3_bind_parameter_count", "int", "sqlite3_stmt*"],
["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"],
["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "int"
- /* We should arguably create a hand-written binding
- which does more flexible text conversion, along the lines of
- sqlite3_prepare_v3(). The slightly problematic part is the
- final argument (text destructor). */
+ /* We should arguably create a hand-written binding of
+ bind_text() which does more flexible text conversion, along
+ the lines of sqlite3_prepare_v3(). The slightly problematic
+ part is the final argument (text destructor). */
],
["sqlite3_close_v2", "int", "sqlite3*"],
["sqlite3_changes", "int", "sqlite3*"],
["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
["sqlite3_compileoption_get", "string", "int"],
["sqlite3_compileoption_used", "int", "string"],
- /* sqlite3_create_function_v2() is handled separate to simplify conversion
- of its callback argument */
+ /* sqlite3_create_function(), sqlite3_create_function_v2(), and
+ sqlite3_create_window_function() use hand-written bindings to
+ simplify handling of their function-type arguments. */
["sqlite3_data_count", "int", "sqlite3_stmt*"],
["sqlite3_db_filename", "string", "sqlite3*", "string"],
["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],
["sqlite3_db_name", "string", "sqlite3*", "int"],
["sqlite3_deserialize", "int", "sqlite3*", "string", "*", "i64", "i64", "int"]
/* Careful! Short version: de/serialize() are problematic because they
- might use a different allocator that the user for managing the
+ might use a different allocator than the user for managing the
deserialized block. de/serialize() are ONLY safe to use with
sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. */,
["sqlite3_errmsg", "string", "sqlite3*"],
/* sqlite3_prepare_v2() and sqlite3_prepare_v3() are handled
separately due to us requiring two different sets of semantics
for those, depending on how their SQL argument is provided. */
+ /* sqlite3_randomness() uses a hand-written wrapper to extend
+ the range of supported argument types. */
["sqlite3_realloc", "*","*","int"],
["sqlite3_reset", "int", "sqlite3_stmt*"],
["sqlite3_result_blob",undefined, "*", "*", "int", "*"],
throw new SQLite3Error(...args);
};
+ capi.sqlite3_randomness = (...args)=>{
+ 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);
+ return ta;
+ }
+ const stack = wasm.pstack.pointer;
+ try {
+ let n = ta.byteLength, offset = 0;
+ const r = wasm.exports.sqlite3_randomness;
+ const heap = wasm.heap8u();
+ const nAlloc = n < 512 ? n : 512;
+ const ptr = wasm.pstack.alloc(nAlloc);
+ do{
+ const j = (n>nAlloc ? nAlloc : n);
+ r(j, ptr);
+ ta.set(typedArrayPart(heap, ptr, ptr+j), offset);
+ n -= j;
+ offset += j;
+ } while(n > 0);
+ }catch(e){
+ console.error("Highly unexpected (and ignored!) "+
+ "exception in sqlite3_randomness():",e);
+ }finally{
+ wasm.pstack.restore(stack);
+ }
+ return ta;
+ }
+ capi.wasm.exports.sqlite3_randomness(...args);
+ };
+
/** State for sqlite3_wasmfs_opfs_dir(). */
- let __persistentDir = undefined;
+ let __wasmfsOpfsDir = undefined;
/**
If the wasm environment has a WASMFS/OPFS-backed persistent
storage directory, its path is returned by this function. If it
Emscripten-managed virtual filesystem.
*/
capi.sqlite3_wasmfs_opfs_dir = function(){
- if(undefined !== __persistentDir) return __persistentDir;
+ if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
// If we have no OPFS, there is no persistent dir
const pdir = config.wasmfsOpfsDir;
if(!pdir
|| !self.FileSystemHandle
|| !self.FileSystemDirectoryHandle
|| !self.FileSystemFileHandle){
- return __persistentDir = "";
+ return __wasmfsOpfsDir = "";
}
try{
if(pdir && 0===wasm.xCallWrapped(
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
)){
- return __persistentDir = pdir;
+ return __wasmfsOpfsDir = pdir;
}else{
- return __persistentDir = "";
+ return __wasmfsOpfsDir = "";
}
}catch(e){
// sqlite3_wasm_init_wasmfs() is not available
- return __persistentDir = "";
+ return __wasmfsOpfsDir = "";
}
};
-C Disable\sthe\spush-down\soptimization\sfor\ssub-queries\sthat\sare\sINTERSECT,\sUNION\sor\sEXCEPT\scompounds.\sdbsqlfuzz\sa34f455c91ad75a0cf8cd9476841903f42930a7a.
-D 2022-10-26T21:14:21.853
+C Expose\ssqlite3_randomness()\sto\sWASM\sand\sadd\sa\scustom\sbinding\sfor\sit\swhich\scan\spopulate\sa\sJS\sbyte\sarray.\sAdd\sWhWasmUtil.isPtr().
+D 2022-10-27T03:03:16.460
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/wasm/GNUmakefile 7a8c06f9bdbb791f8ef084ecd47e099da81e5797b9b1d60e33ac9a07eedd5dbd
F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20
F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8a3066
-F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 36f413ab4dbb057d2dec938fb366ac0a4c5e85ba14660a8d672f0277602c0fc5
+F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api cfbe8efcb9d1444139d6c381eb54dfdd5e62cf1ddfe10ed8a38617149a664b9b
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md 1350088aee90e959ad9a94fab1bb6bcb5e99d4d27f976db389050f54f2640c78
F ext/wasm/api/extern-post-js.js 926d192b72fa808378e5e7843721dc7ba3908c163a0260e06d8aa501c12f5469
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
F ext/wasm/api/pre-js.js 151e0616614a49f3db19ed544fa13b38c87c108959fbcd4029ea8399a562d94f
F ext/wasm/api/sqlite3-api-cleanup.js 4d07a7524dc9b7b050acfde57163e839243ad2383bd7ee0de0178b1b3e988588
-F ext/wasm/api/sqlite3-api-glue.js 6e4e472eb5afc732a695cd7c5ded6dee6ef8b480e61aa0d648a3fc9033c84745
+F ext/wasm/api/sqlite3-api-glue.js f024dc2f41418ad203edf1228d7cf7934249c11ffcbb65d21f9bb69333d63d55
F ext/wasm/api/sqlite3-api-oo1.js 38004e18001396c078124769e14737a0ff703f98317279734020121af72efdd5
F ext/wasm/api/sqlite3-api-opfs.js 62da8b7cac30d4e7bb940762d2ac948b0aeb89704a5a290b74eb268ecbd1a64e
-F ext/wasm/api/sqlite3-api-prologue.js fa00d55f927e5a4ec51cf2c80f6f0eaed2f4f5774341ecf3d63a0ea4c738f8f5
+F ext/wasm/api/sqlite3-api-prologue.js 4706ca7fa125426019b8dd01f9e6a774021a2781874df8b9f435c69544383e79
F ext/wasm/api/sqlite3-api-worker1.js b2d650514ccc75f80dff666fd3ee68dc8fb4137bcd01caac2c62ff93a7ebf638
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
F ext/wasm/api/sqlite3-opfs-async-proxy.js f04cb1eb483c92bc61fe02749f7afcf17ec803968171aedd7d96faf428c26bcb
F ext/wasm/common/SqliteTestUtil.js 647bf014bd30bdd870a7e9001e251d12fc1c9ec9ce176a1004b838a4b33c5c05
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/common/testing.css 739b58c44511f642f16f57b701c84dc9ee412d8bc47b3d8a99d947babfa69d9d
-F ext/wasm/common/whwasmutil.js 50d2ede0b0fa01c1d467e1801fab79f5e46bb02bcbd2b0232e4fdc6090a47818
+F ext/wasm/common/whwasmutil.js 77930367c2a65cf6fd6f99ad3644ede33e4d20466f5e506eb87b8d101a0a7655
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
F ext/wasm/test-opfs-vfs.js 48fc59110e8775bb43c9be25b6d634fc07ebadab7da8fbd44889e8129c6e2548
F ext/wasm/tester1-worker.html d02b9d38876b023854cf8955e77a40912f7e516956b4dbe1ec7f215faac273ee
F ext/wasm/tester1.html c6c47e5a8071eb09cb1301104435c8e44fbb5719c92411f5b2384a461f9793c5
-F ext/wasm/tester1.js 21dad63165954a8a28dfa8eeab68a4881eb1d9b5c6bc9f2c83aa3ceea8c41fee
+F ext/wasm/tester1.js 39dd4277944f79f475d78850ebbf48b0fe61b2caf4df2b5c5db6219f509d5c96
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
F ext/wasm/wasmfs.make ee0004813e16c283ff633e08b482008d56adf9b7d42f6c5612f7ab002b924f69
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a029dddff4f4ed7275538610cbd9cea658b905b72924860ec9cda9e76dabcfac
-R b53abb7e437a17a51c11b8e565290cc0
-U dan
-Z f234279171f2df9582a4a9e673101d04
+P 346a3b12b861ce7ba369e98cd336f79a1d4f7a7bb9acd7a4f63f37b391755bf5
+R 5867ff413088cae7742d2b15dc451b3e
+U stephan
+Z c456212142f768a2abd7eb0069fb1a57
# Remove this line to create a well-formed Fossil manifest.