From: stephan Date: Thu, 3 Aug 2023 21:14:58 +0000 (+0000) Subject: Retain all xDestroy method WASM proxies created for fts5_api::xCreateFunction() until... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=75c60b46568264e577264c7f8eea914bb5b7b027;p=thirdparty%2Fsqlite.git Retain all xDestroy method WASM proxies created for fts5_api::xCreateFunction() until the db is closed, then free them all at once. FossilOrigin-Name: f4b9743abd4fe24f1604cbcc7f9f95cadd1cefdc053eeabb35dc6773c99d1277 --- diff --git a/ext/wasm/api/sqlite3-fts5-helper.js b/ext/wasm/api/sqlite3-fts5-helper.js index 09e3db8bed..f1b169afde 100644 --- a/ext/wasm/api/sqlite3-fts5-helper.js +++ b/ext/wasm/api/sqlite3-fts5-helper.js @@ -56,22 +56,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } }); - /* JS-to-WASM arg adapter for xCreateFunction()'s xDestroy arg. */ - const xDestroyArgAdapter = new wasm.xWrap.FuncPtrAdapter({ - name: 'fts5_api::xCreateFunction(xDestroy)', - signature: 'v(p)', - contextKey: xFunctionArgAdapter.contextKey, - callProxy: (callback)=>{ - return (pArg)=>{ - try{ callback(pArg) } - catch(e){ - sqlite3.config.warn("FTS5 function xDestroy() threw. Ignoring.",e); - } - } - } - }); - - /** Map of (sqlite3*) to fts.fts5_api. */ const __ftsApiToStruct = Object.create(null); const __fts5_api_from_db = function(pDb, createIfNeeded){ @@ -86,11 +70,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Arrange for WASM functions dynamically created via this API to be uninstalled when the db they were installed for is closed... */ - const __addCleanupForFunc = function(sfapi, name){ - if(!sfapi.$$funcNames){ - sfapi.$$funcNames = new Set; + const __addCleanupForFunc = function(sfapi, name, pDestroy){ + if(!sfapi.$$cleanup){ + sfapi.$$cleanup = new Set; } - sfapi.$$funcNames.add(name.toLowerCase()); + sfapi.$$cleanup.add([name.toLowerCase(), pDestroy]); }; /** @@ -103,17 +87,19 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const sfapi = __fts5_api_from_db(pDb, false); if(sfapi){ delete __ftsApiToStruct[pDb]; - if(sfapi.$$funcNames){ + if(sfapi.$$cleanup){ const fapi = sfapi.pointer; const scope = wasm.scopedAllocPush(); //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; try{ - for(const name of sfapi.$$funcNames){ + for(const [name, pDestroy] of sfapi.$$cleanup){ try{ + /* Uninstall xFunctionArgAdapter's bindings via a + roundabout approach... */ const zName = wasm.scopedAllocCString(name); const argv = [fapi, zName, 0, 0, 0]; xFunctionArgAdapter.convertArg(0, argv, 3); - xDestroyArgAdapter.convertArg(0, argv, 4); + if(pDestroy) wasm.uninstallFunction(pDestroy); }catch(e){ sqlite3.config.error("Error removing FTS func",name,e); } @@ -142,7 +128,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ installed for the life of the given db handle. The function must return void and accept args in the form (ptrToFts5ExtensionApi, ptrToFts5Context, ptrToSqlite3Context, - array-of-values). + array-of-JS-values). - xDestroy optional Function or pointer to WASM function to call when the binding is destroyed (when the db handle is @@ -171,16 +157,27 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const fapi = fts.fts5_api_from_db(db) || toss("Internal error - cannot get FTS5 API object for db."); const sfapi = __fts5_api_from_db(db, true); + let pDestroy = 0; try{ + /** Because of how fts5_api::xCreateFunction() replaces + functions (by prepending new ones to a linked list but + retaining old ones), we cannot use a FuncPtrAdapter to + automatically convert xDestroy, lest we end up uninstalling + a bound-to-wasm JS function's wasm pointer before fts5 + cleans it up when the db is closed. */ + if(xDestroy instanceof Function){ + pDestroy = wasm.installFunction(xDestroy, 'v(p)'); + } const xcf = sfapi.$$xCreateFunction || ( sfapi.$$xCreateFunction = wasm.xWrap(sfapi.$xCreateFunction, 'int', [ - '*', 'string', '*', xFunctionArgAdapter, xDestroyArgAdapter + '*', 'string', '*', xFunctionArgAdapter, '*' ]) ); - const rc = xcf(fapi, name, 0, xFunction || 0, xDestroy || 0 ); + const rc = xcf(fapi, name, 0, xFunction || 0, pDestroy || xDestroy || 0 ); if(rc) toss(rc,"FTS5::xCreateFunction() failed."); - __addCleanupForFunc(sfapi, name); + __addCleanupForFunc(sfapi, name, pDestroy); }catch(e){ + if(pDestroy) wasm.uninstallFunction(pDestroy); sfapi.dispose(); throw e; } diff --git a/manifest b/manifest index 8c61ea30a1..95724e0aeb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rework\sthe\sfts5\sdb-close\scleanup\sto\savoid\sthat\sfts5\sinternally\scalls\sa\sjust-unbound-from-wasm\sxDestroy()\smethod.\sThere\sis\sstill\swork\sto\sdo\shere\sto\scover\sthe\scase\sof\sfts5\sfunctions\sbeing\sreplaced\s(in\swhich\sall\sxDestroy\smethods\shave\sto\sbe\sretained\suntil\sthe\sdb\sis\sclosed). -D 2023-08-03T20:45:28.696 +C Retain\sall\sxDestroy\smethod\sWASM\sproxies\screated\sfor\sfts5_api::xCreateFunction()\suntil\sthe\sdb\sis\sclosed,\sthen\sfree\sthem\sall\sat\sonce. +D 2023-08-03T21:14:58.401 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -505,7 +505,7 @@ F ext/wasm/api/sqlite3-api-glue.js 861ff5ccfbaa50579c46618be53ac374202ad73cc27eb F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8 F ext/wasm/api/sqlite3-api-prologue.js 76258e160bf6a89cc75a7d3c05646a054c8cab7219cd1e10bc20cacaad022131 F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec -F ext/wasm/api/sqlite3-fts5-helper.js 8d7a35e18463102fe2783657d5c59c3c0c7460f0eb699757ebfed2e44df2a001 +F ext/wasm/api/sqlite3-fts5-helper.js c5da57d586f2689ea79f6c0d78f5b6a31af8c1234eee8e2ecc4ee5dee49e61d2 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379 F ext/wasm/api/sqlite3-v-helper.js 8dc3da6e69d51f455b64cc88fec7977f528d79ec267cfcdd97b606c8cc4cd156 @@ -2051,8 +2051,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 ce0674b1925138f8f878b11aae0f8420bd968df0959f6dd7e208fb84bcbad07e -R 55a64755ba6bd7e4b55de6971891bfd0 +P 795f22421b96cea27b3883a580d8ce29cc50dfb7d4f852b3d36ede3766c7a24c +R 1ffc481fbc423b6f11fdbf02fdf3e96b U stephan -Z 971bc1dc41287f5b57d1768c8e038762 +Z eb3f6a64812695d4286c7946c1459803 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1163b9af10..7951d5e102 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -795f22421b96cea27b3883a580d8ce29cc50dfb7d4f852b3d36ede3766c7a24c \ No newline at end of file +f4b9743abd4fe24f1604cbcc7f9f95cadd1cefdc053eeabb35dc6773c99d1277 \ No newline at end of file