}
});
- /* 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){
/**
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]);
};
/**
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);
}
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
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;
}
-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
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
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.