From feb9123a8cc018fd0765ef47e1f5bad5b5b3f2aa Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 14 Dec 2022 14:28:54 +0000 Subject: [PATCH] Add convenience variants of sqlite3.wasm.peek/poke() for each numeric type to help reduce errors related to typos in the final argument (type-name strings). If wasm.xWrap.FuncPtrAdapter is called as a function, instead of a constructor, it now behaves as if it were called as a constructor (previously it threw an exception). FossilOrigin-Name: 14e3fc01b929fa3f9a2fdbd93deb4a8aad58c111d46369c772def0437152fa75 --- ext/wasm/api/sqlite3-api-glue.js | 4 +-- ext/wasm/api/sqlite3-api-oo1.js | 5 ++-- ext/wasm/common/whwasmutil.js | 51 ++++++++++++++++++++++++++++---- ext/wasm/tester1.c-pp.js | 20 +++++++++++++ manifest | 18 +++++------ manifest.uuid | 2 +- 6 files changed, 80 insertions(+), 20 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 21dd34d136..972b4a2e08 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -138,7 +138,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ the range of supported argument types. */ [ "sqlite3_progress_handler", undefined, [ - "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({ + "sqlite3*", "int", wasm.xWrap.FuncPtrAdapter({ name: 'xProgressHandler', signature: 'i(p)', bindScope: 'context', @@ -180,7 +180,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "**", "**", "*", "*", "*"], ["sqlite3_total_changes", "int", "sqlite3*"], ["sqlite3_trace_v2", "int", "sqlite3*", "int", - new wasm.xWrap.FuncPtrAdapter({ + wasm.xWrap.FuncPtrAdapter({ name: 'sqlite3_trace_v2::callback', signature: 'i(ippp)', contextKey: (argIndex, argv)=>'sqlite3@'+argv[0] diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index adfcca4d94..59ecf56b96 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -442,9 +442,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }else if('string'===typeof opt.rowMode && opt.rowMode.length>1){ /* "$X": fetch column named "X" (case-sensitive!). Prior to 2022-12-14 ":X" and "@X" were also permitted, but - that seems unnecessary and likely to cause - confusion. $ is the clear usability winner because it - doesn't require quoting in JS. */ + having so many options is unnecessary and likely to + cause confusion. */ if('$'===opt.rowMode[0]){ out.cbArg = function(stmt){ const rc = stmt.get(this.obj)[this.colName]; diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 3d137eb008..d607799c8e 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -759,13 +759,51 @@ self.WhWasmUtilInstaller = function(target){ target.peekPtr = (...ptr)=>target.peek( (1===ptr.length ? ptr[0] : ptr), ptrIR ); /** - A variant of poke() intended for setting - pointer-to-pointer values. Its differences from poke() are - that (1) it defaults to a value of 0, (2) it always writes - to the pointer-sized heap view, and (3) it returns `this`. + A variant of poke() intended for setting pointer-to-pointer + values. Its differences from poke() are that (1) it defaults to a + value of 0 and (2) it always writes to the pointer-sized heap + view. */ target.pokePtr = (ptr, value=0)=>target.poke(ptr, value, ptrIR); + /** + Convenience form of peek() intended for fetching i8 values. If + passed a single non-array argument it returns the value of that + one pointer address. If passed multiple arguments, or a single + array of arguments, it returns an array of their values. + */ + target.peek8 = (...ptr)=>target.peek( (1===ptr.length ? ptr[0] : ptr), 'i8' ); + /** + Convience form of poke() intended for setting individual bytes. + Its difference from poke() is that it always writes to the + i8-sized heap view. + */ + target.poke8 = (ptr, value)=>target.poke(ptr, value, 'i8'); + /** i16 variant of peek8(). */ + target.peek16 = (...ptr)=>target.peek( (1===ptr.length ? ptr[0] : ptr), 'i16' ); + /** i16 variant of poke8(). */ + target.poke16 = (ptr, value)=>target.poke(ptr, value, 'i16'); + /** i32 variant of peek8(). */ + target.peek32 = (...ptr)=>target.peek( (1===ptr.length ? ptr[0] : ptr), 'i32' ); + /** i32 variant of poke8(). */ + target.poke32 = (ptr, value)=>target.poke(ptr, value, 'i32'); + /** i64 variant of peek8(). Will throw if this build is not + configured for BigInt support. */ + target.peek64 = (...ptr)=>target.peek( (1===ptr.length ? ptr[0] : ptr), 'i64' ); + /** i64 variant of poke8(). Will throw if this build is not + configured for BigInt support. Note that this returns + a BigInt-type value, not a Number-type value. */ + target.poke64 = (ptr, value)=>target.poke(ptr, value, 'i64'); + /** f32 variant of peek8(). */ + target.peekF32 = (...ptr)=>target.peek( (1===ptr.length ? ptr[0] : ptr), 'f32' ); + /** f32 variant of poke8(). */ + target.pokeF32 = (ptr, value)=>target.poke(ptr, value, 'f32'); + /** f64 variant of peek8(). */ + target.peekF64 = (...ptr)=>target.peek( (1===ptr.length ? ptr[0] : ptr), 'f64' ); + /** f64 variant of poke8(). */ + target.pokeF64 = (ptr, value)=>target.poke(ptr, value, 'f64'); + + /** Deprecated alias for getMemValue() */ target.getMemValue = target.peek; /** Deprecated alias for peekPtr() */ @@ -1509,10 +1547,13 @@ self.WhWasmUtilInstaller = function(target){ The constructor only saves the above state for later, and does not actually bind any functions. Its convertArg() method is called via xWrap() to perform any bindings. + + If this is called like a function, instead of a constructor, + it behaves as if it were called like a constructor. */ xArg.FuncPtrAdapter = function ctor(opt) { if(!(this instanceof xArg.FuncPtrAdapter)){ - toss("FuncPtrAdapter can only be used as a constructor. Use 'new'."); + return new xArg.FuncPtrAdapter(opt); } this.signature = opt.signature; if(!opt.bindScope && (opt.contextKey instanceof Function)){ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 21ff7b0341..81593bc211 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -480,6 +480,7 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(u[i] === byteList[i]) .assert(u[i] === w.peek(m + i, 'i8')); } + w.dealloc(m); T.mustThrowMatching( ()=>w.allocFromTypedArray(1), @@ -487,6 +488,25 @@ self.sqlite3InitModule = sqlite3InitModule; ); } + { // Test peekXYZ()/pokeXYZ()... + const m = w.alloc(8); + T.assert( 17 === w.poke8(m,17).peek8(m) ) + .assert( 31987 === w.poke16(m,31987).peek16(m) ) + .assert( 345678 === w.poke32(m,345678).peek32(m) ) + .assert( + T.eqApprox( 345678.9, w.pokeF32(m,345678.9).peekF32(m) ) + ).assert( + T.eqApprox( 4567890123.4, w.pokeF64(m, 4567890123.4).peekF64(m) ) + ); + if(w.bigIntEnabled){ + T.assert( + BigInt(Number.MAX_SAFE_INTEGER) === + w.poke64(m, Number.MAX_SAFE_INTEGER).peek64(m) + ); + } + w.dealloc(m); + } + // isPtr32() { const ip = w.isPtr32; diff --git a/manifest b/manifest index 98f728b676..cdf27d20da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\sto\sdemonstrate/verify\swhich\sobject\sacts\sas\s"this"\sin\sa\soo1.DB.exec()\scallback. -D 2022-12-14T08:12:01.264 +C Add\sconvenience\svariants\sof\ssqlite3.wasm.peek/poke()\sfor\seach\snumeric\stype\sto\shelp\sreduce\serrors\srelated\sto\stypos\sin\sthe\sfinal\sargument\s(type-name\sstrings).\sIf\swasm.xWrap.FuncPtrAdapter\sis\scalled\sas\sa\sfunction,\sinstead\sof\sa\sconstructor,\sit\snow\sbehaves\sas\sif\sit\swere\scalled\sas\sa\sconstructor\s(previously\sit\sthrew\san\sexception). +D 2022-12-14T14:28:54.534 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,8 +503,8 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 247e3777c921134e479129b54883cf1090d57093b23487917a7b29e151f4def3 -F ext/wasm/api/sqlite3-api-oo1.js 238e7f926127f03b4ce858fc9ae24e1f1df87c8fdd63812e452f6e74add4a917 +F ext/wasm/api/sqlite3-api-glue.js a8010bf3fa184886d1e9e76b0d0d1e290b5fa25130510644a59e91a18f779ef4 +F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6 F ext/wasm/api/sqlite3-api-prologue.js 86eb4488f2be85e68c23ebcfad0834c24b6075e1645c67890cc4163c462efac1 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js b4548b24c10e9cba674f110809693e5eb5722b59b15a939377e2c380e9458168 +F ext/wasm/common/whwasmutil.js d8167cf3b02ad2376b86d81e728b7460b4ee7044c60fb547b24df650158cfc3b F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js c509200426b16a1492d4eb96ecc43f7969d89f0f5696390a298a6593060e94f0 +F ext/wasm/tester1.c-pp.js c3e773ea73102d71ec65b84b9c11d1e8ba5bae7120becacda0afc33f27c85d44 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 82a6c7fdf59729c182545b15c084b136e34513f340e87a7b6e5aa199117357b0 -R 699d3a7ac36ecd1e55471da702ad608c +P 8fc4b3f10f61e965853a22bf7a64ad2511ef656d66658a7910bac35b0f9805ec +R 956750acad49982af078888e9331781e U stephan -Z 7d0c7fa7d39a31e4b43642e1d9b23737 +Z 5c4ee894557c0103a5bb5ffb259a8752 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 947f217e32..af51d02cc2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8fc4b3f10f61e965853a22bf7a64ad2511ef656d66658a7910bac35b0f9805ec \ No newline at end of file +14e3fc01b929fa3f9a2fdbd93deb4a8aad58c111d46369c772def0437152fa75 \ No newline at end of file