diff options
author | stephan <stephan@noemail.net> | 2023-08-04 08:45:25 +0000 |
---|---|---|
committer | stephan <stephan@noemail.net> | 2023-08-04 08:45:25 +0000 |
commit | a24769454e2ddd05d543d9b3cf20401cf6c43bdb (patch) | |
tree | b17826baca838c53a112edaf544bf6b23088ffd8 /ext/wasm/common/whwasmutil.js | |
parent | 444424dab8c5fff24256ab32f0279e3e0b841961 (diff) | |
download | sqlite-a24769454e2ddd05d543d9b3cf20401cf6c43bdb.tar.gz sqlite-a24769454e2ddd05d543d9b3cf20401cf6c43bdb.zip |
Resolve the timing/ordering issue of a JS-to-WASM-converted xDestroy() function being uninstalled from WASM right before the underlying native call tries to call it. This has been a long-unnoticed bug which appears only when removing such functions or replacing them.
FossilOrigin-Name: 031c9a76b6ad1572e7a88f4d2d62f206b0d37bd1170e2c8a24248c5ec628f2f5
Diffstat (limited to 'ext/wasm/common/whwasmutil.js')
-rw-r--r-- | ext/wasm/common/whwasmutil.js | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 4a6934f71..0437ef35d 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -613,8 +613,6 @@ globalThis.WhWasmUtilInstaller = function(target){ target.installFunction = (func, sig)=>__installFunction(func, sig, false); /** - EXPERIMENTAL! DO NOT USE IN CLIENT CODE! - Works exactly like installFunction() but requires that a scopedAllocPush() is active and uninstalls the given function when that alloc scope is popped via scopedAllocPop(). @@ -1722,7 +1720,18 @@ globalThis.WhWasmUtilInstaller = function(target){ FuncPtrAdapter.debugOut("FuncPtrAdapter uninstalling", this, this.contextKey(argv,argIndex), '@'+pair[1], v); } - try{target.uninstallFunction(pair[1])} + try{ + /* Because the pending native call might rely on the + pointer we're replacing, e.g. as is normally the case + with sqlite3's xDestroy() methods, we don't + immediately uninstall but instead add its pointer to + the scopedAlloc stack, which will be cleared when the + xWrap() mechanism is done calling the native + function. We're relying very much here on xWrap() + having pushed an alloc scope. + */ + cache.scopedAlloc[cache.scopedAlloc.length-1].push(pair[1]); + } catch(e){/*ignored*/} } pair[0] = v; |