From: stephan Date: Wed, 26 Jul 2023 18:11:40 +0000 (+0000) Subject: Initial experimentation with getting JSPI (JavaScript Promise Integration) support... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=028ea503659148304598ae45d06093cb3092959a;p=thirdparty%2Fsqlite.git Initial experimentation with getting JSPI (JavaScript Promise Integration) support working. It builds, but requires disabling func argument count validation checks on sqlite3.wasm.xWrap()-processed exports and it crashes cryptically in wasm when the tests are run. FossilOrigin-Name: 5b178f92f5faea83734aeacf79a06a8fcfc2f392db5d430d2c083b4d2ff4af5f --- diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 3cd1d930af..e3a7955c79 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -429,6 +429,10 @@ emcc.flags += -v # -v is _very_ loud but also informative about what it's doing endif +# ENABLE_JSPI does not yet work. This flag is only for use during +# experimentation with it. +ENABLE_JSPI ?= 1 + ######################################################################## # emcc flags for .c/.o. emcc.cflags := @@ -451,7 +455,9 @@ emcc.exportedRuntimeMethods := \ emcc.jsflags += $(emcc.exportedRuntimeMethods) emcc.jsflags += -sUSE_CLOSURE_COMPILER=0 emcc.jsflags += -sIMPORTED_MEMORY -#emcc.jsflags += -sASYNCIFY=2 +ifeq (1,$(ENABLE_JSPI)) + emcc.jsflags += -sASYNCIFY=2 +endif # ^^^ ASYNCIFY=2 is for experimental JSPI support # (https://v8.dev/blog/jspi), but enabling it causes the lib-level # init code to throw inexplicable complaints about C-level function @@ -780,11 +786,19 @@ sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs #$(info $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0, $(sqlite3-api.js), $(sqlite3.js))) +ifeq (1,$(ENABLE_JSPI)) + c-pp.D.jspi := -Djspi +else + c-pp.D.jspi := +endif + $(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0,\ - $(sqlite3-api.js), $(sqlite3.js))) + $(sqlite3-api.js), $(sqlite3.js),\ + $(c-pp.D.jspi))) $(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,esm,1,\ $(sqlite3-api.mjs), $(sqlite3.mjs), \ - -Dtarget=es6-module, -sEXPORT_ES6 -sUSE_ES6_IMPORT_META)) + -Dtarget=es6-module $(c-pp.D.jspi),\ + -sEXPORT_ES6 -sUSE_ES6_IMPORT_META)) $(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,bundler-friendly,1,\ $(sqlite3-api-bundler-friendly.mjs),$(sqlite3-bundler-friendly.mjs),\ $(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly)) diff --git a/ext/wasm/api/pre-js.c-pp.js b/ext/wasm/api/pre-js.c-pp.js index 878f3e0546..26995e1139 100644 --- a/ext/wasm/api/pre-js.c-pp.js +++ b/ext/wasm/api/pre-js.c-pp.js @@ -5,6 +5,12 @@ Emscripten's --pre-js=THIS_FILE flag (or equivalent). */ +//#if jspi +// Only to assist in debugging problems which cause loading of the lib +// to break. +globalThis.$EmscriptenModule = Module; +//#endif + // See notes in extern-post-js.js const sqlite3InitModuleState = globalThis.sqlite3InitModuleState || Object.assign(Object.create(null),{ diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index f444ec975c..d4f9918052 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -728,6 +728,10 @@ 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 jspi + wasm.xWrap.doArgcCheck = false; + console.warn("Disabling sqlite3.wasm.xWrap.doArgcCheck for JSPI's sake."); +//#endif for(const e of wasm.bindingSignatures){ capi[e[0]] = wasm.xWrap.apply(null, e); } diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index f48e8a7d21..ccd641bdce 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1391,7 +1391,7 @@ globalThis.WhWasmUtilInstaller = function(target){ target.xCall = function(fname, ...args){ const f = target.xGet(fname); if(!(f instanceof Function)) toss("Exported symbol",fname,"is not a function."); - if(f.length!==args.length) __argcMismatch(fname,f.length) + if(target.xWrap.doArgcCheck && f.length!==args.length) __argcMismatch(fname,f.length) /* This is arguably over-pedantic but we want to help clients keep from shooting themselves in the foot when calling C APIs. */; return (2===arguments.length && Array.isArray(arguments[1])) @@ -1949,7 +1949,7 @@ globalThis.WhWasmUtilInstaller = function(target){ abstracting it into this API (and taking on the associated costs) may well not make good sense. */ - target.xWrap = function(fArg, resultType, ...argTypes){ + target.xWrap = function fw(fArg, resultType, ...argTypes){ if(3===arguments.length && Array.isArray(arguments[2])){ argTypes = arguments[2]; } @@ -1960,10 +1960,16 @@ globalThis.WhWasmUtilInstaller = function(target){ const fIsFunc = (fArg instanceof Function); const xf = fIsFunc ? fArg : target.xGet(fArg); if(fIsFunc) fArg = xf.name || 'unnamed function'; - if(argTypes.length!==xf.length) __argcMismatch(fArg, xf.length); - if((null===resultType) && 0===xf.length){ + if(fw.doArgcCheck && argTypes.length!==xf.length){ + __argcMismatch(fArg, xf.length); + } + if((null===resultType) && 0===xf.length && fw.doArgcCheck){ /* Func taking no args with an as-is return. We don't need a wrapper. We forego the argc check here, though. */ + /* We have to skip this option when !fw.doArgcCheck for the + sake of emcc -sASYNCIFY=2, which adds a nullary wrapper + function to all exports, leading to ALL functions getting + this treatment. */ return xf; } /*Verify the arg type conversions are valid...*/; @@ -1973,14 +1979,14 @@ globalThis.WhWasmUtilInstaller = function(target){ else __xArgAdapterCheck(t); } const cxw = cache.xWrap; - if(0===xf.length){ + if(0===xf.length && fw.doArgcCheck/*see notes above*/){ // No args to convert, so we can create a simpler wrapper... return (...args)=>(args.length ? __argcMismatch(fArg, xf.length) : cxw.convertResult(resultType, xf.call(null))); } return function(...args){ - if(args.length!==xf.length) __argcMismatch(fArg, xf.length); + if(fw.doArgcCheck && args.length!==xf.length) __argcMismatch(fArg, xf.length); const scope = target.scopedAllocPush(); try{ /* @@ -2008,6 +2014,15 @@ globalThis.WhWasmUtilInstaller = function(target){ } }; }/*xWrap()*/; + /** + By default xWrap() asserts that wrapper functions have the + same arity as the native functions being wrapped. This sanity + check has saved many grey hairs in development and generally + should not be disabled. However, Emscripten's -sASYNCIFY=2 flag + adds a level of wrapper to exported functions, giving them all + an arity of 0. This check must be suppressed for that case. + */ + target.xWrap.doArgcCheck = true; /** Internal impl for xWrap.resultAdapter() and argAdapter(). */ const __xAdapter = function(func, argc, typeName, adapter, modeName, xcvPart){ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index db4b50f4b6..fa9cc142ae 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -728,12 +728,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule; //log("xWrap()..."); { - T.mustThrowMatching(()=>w.xWrap('sqlite3_libversion',null,'i32'), - /requires 0 arg/). - assert(w.xWrap.resultAdapter('i32') instanceof Function). - assert(w.xWrap.argAdapter('i32') instanceof Function); let fw = w.xWrap('sqlite3_libversion','utf8'); - T.mustThrowMatching(()=>fw(1), /requires 0 arg/); + if(w.xWrap.doArgcCheck){ + T.mustThrowMatching(()=>w.xWrap('sqlite3_libversion',null,'i32'), + /requires 0 arg/). + assert(w.xWrap.resultAdapter('i32') instanceof Function). + assert(w.xWrap.argAdapter('i32') instanceof Function); + T.mustThrowMatching(()=>fw(1), /requires 0 arg/); + } let rc = fw(); T.assert('string'===typeof rc).assert(rc.length>5); rc = w.xCallWrapped('sqlite3_wasm_enum_json','*'); diff --git a/manifest b/manifest index 9e1a1f3698..911d11477b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sbatch\sSQL\srunner\sfrom\sthe\sJS\sbuild's\s'all'\starget,\sas\sit's\slong-since\sunused\sand\sadds\snoticable\sbuild\stime.\sAdd\smakefile\scomments\sabout\sJSPI. -D 2023-07-26T11:41:41.032 +C Initial\sexperimentation\swith\sgetting\sJSPI\s(JavaScript\sPromise\sIntegration)\ssupport\sworking.\sIt\sbuilds,\sbut\srequires\sdisabling\sfunc\sargument\scount\svalidation\schecks\son\ssqlite3.wasm.xWrap()-processed\sexports\sand\sit\scrashes\scryptically\sin\swasm\swhen\sthe\stests\sare\srun. +D 2023-07-26T18:11:40.333 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -482,7 +482,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile ddf1aede4275e404c7eda782462c33b6406fcd2dd327241f6b22c0f7b80938e4 +F ext/wasm/GNUmakefile d5e296c96c2c2bf4ea77b1ea4962096aef79daa45bc610f55a9f7cb43b103748 F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 F ext/wasm/README.md 0895244c0539ae68cf8c70d59c2de512532fd47cfba313268e2b672e6359112e F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab @@ -493,9 +493,9 @@ F ext/wasm/api/extern-post-js.c-pp.js e7257ea56d4077d0773d7537fcb8eade59aad0c118 F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 -F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219 +F ext/wasm/api/pre-js.c-pp.js 572c762b53101781b5e1c35dc62729e3eda616d113153f8199df843a7c1ff6da F ext/wasm/api/sqlite3-api-cleanup.js 23ceec5ef74a0e649b19694ca985fd89e335771e21f24f50df352a626a8c81bf -F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803 +F ext/wasm/api/sqlite3-api-glue.js 47843a29fb894f8d4b580cc7789f5c9ceaf6fcb9502a43df03db2bfbc4611f77 F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8 F ext/wasm/api/sqlite3-api-prologue.js cbd7d6ba185f3a844a8b0020e954b49bbc2ca78b305d117bec2ceca21431795a F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec @@ -513,7 +513,7 @@ F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25 F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f -F ext/wasm/common/whwasmutil.js ae263dec9d7384f4c530f324b99d00516a4d6f26424372daee65031e00eb49b3 +F ext/wasm/common/whwasmutil.js eb115cef76f568223129b659a4f0212f2e0c5fdfa6d8429c6a5382b140edd217 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js 38aa8faec4d0ace1c973bc8a7a1533584463ebeecd4c420daa7d9687beeb9cb5 @@ -549,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js b9a493a764f2113f6a8205d4e5573a25731d6f965338005460920389ac0693e0 +F ext/wasm/tester1.c-pp.js 2b30bdf9d29f6db37b2599188296389ab097b3137be208c0b5aca1cb1b412ba1 F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2044,8 +2044,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 72dc3f8c3255186ec412412b685b0b51ddcd08240f2353ac742fc7da8c23568e -R 9fd280b1c194f8e5991f01cbec9ff41b +P b8f708e35d4fa027d12089ac7c5589c36da5f68b98cf9792bb11276bf233a860 +R b579c0cc362e441177477b3883fcf994 +T *branch * jspi +T *sym-jspi * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z 790924414d34e6bddbbcb85cdb1bbe6d +Z 37b78cb422886750d5650a379168ec92 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 70d28d9e10..96c848e7aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b8f708e35d4fa027d12089ac7c5589c36da5f68b98cf9792bb11276bf233a860 \ No newline at end of file +5b178f92f5faea83734aeacf79a06a8fcfc2f392db5d430d2c083b4d2ff4af5f \ No newline at end of file