mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Add a more complete test for [76c8435a] and add some commentary about (A) the inability to automatically clean up automatically-generated WASM proxy functions for sqlite3_set_auxdata() destructors and (B) how to deal with (A) to avoid leaking WASM proxy functions.
FossilOrigin-Name: d693c2dddbd10a2e0b77893b04b11502e30b768f1b06814105f7f35172845fb9
This commit is contained in:
@ -3437,6 +3437,73 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
}
|
||||
}
|
||||
})
|
||||
.t({
|
||||
/* https://github.com/sqlite/sqlite-wasm/issues/92 */
|
||||
name: 'sqlite3_set_auxdata() binding signature',
|
||||
test: function(sqlite3){
|
||||
const db = new sqlite3.oo1.DB();
|
||||
const stack = wasm.pstack.pointer;
|
||||
const pAux = wasm.pstack.alloc(4);
|
||||
let pAuxDestructed = 0;
|
||||
const args = [];
|
||||
const pAuxDtor = wasm.installFunction('v(p)', function(ptr){
|
||||
//log("freeing auxdata");
|
||||
++pAuxDestructed;
|
||||
});
|
||||
let pAuxDtorDestructed = false;
|
||||
db.onclose = {
|
||||
after: ()=>{
|
||||
pAuxDtorDestructed = true;
|
||||
wasm.uninstallFunction(pAuxDtor);
|
||||
}
|
||||
};
|
||||
try{
|
||||
db.createFunction("auxtest",{
|
||||
xFunc: function(pCx, x, y){
|
||||
args.push(x);
|
||||
T.assert(wasm.isPtr(pCx));
|
||||
const localAux = capi.sqlite3_get_auxdata(pCx, 0);
|
||||
if( !localAux ){
|
||||
//log("setting auxdata");
|
||||
/**
|
||||
We do not currently an automated way to clean up
|
||||
auxdata finalizer functions (the 4th argument to
|
||||
sqlite3_set_auxdata()) which get automatically
|
||||
converted from JS to WASM. Because of that, relying
|
||||
on automated conversions for those is not
|
||||
recommended. Instead, follow the pattern show in
|
||||
this function: use wasm.installFunction() to create
|
||||
the function, then pass the resulting function
|
||||
pointer this function, and cleanup (at some point)
|
||||
using wasm.uninstallFunction().
|
||||
*/
|
||||
capi.sqlite3_set_auxdata(pCx, 0, pAux, pAuxDtor);
|
||||
}else{
|
||||
/* This is never actually hit in this example and it's
|
||||
not entirely clear how to cause it to. The point of
|
||||
this test, however, is to demonstrate that the
|
||||
finalizer impl gets triggered, so we're not going to
|
||||
fret over this at the moment. */
|
||||
//log("seen auxdata",localAux);
|
||||
T.assert(pAux===localAux);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
});
|
||||
db.exec([
|
||||
"create table t(a);",
|
||||
"insert into t(a) values(1),(2),(3);",
|
||||
"select auxtest(a,a), auxtest(a,a) from t order by a"
|
||||
]);
|
||||
}finally{
|
||||
db.close();
|
||||
wasm.pstack.restore(stack);
|
||||
}
|
||||
T.assert(6===args.length);
|
||||
T.assert(pAuxDestructed>0);
|
||||
T.assert(pAuxDtorDestructed);
|
||||
}
|
||||
})
|
||||
;/*end of Bug Reports group*/;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
Reference in New Issue
Block a user