aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm')
-rw-r--r--ext/wasm/api/sqlite3-api-glue.c-pp.js29
-rw-r--r--ext/wasm/tester1.c-pp.js67
2 files changed, 96 insertions, 0 deletions
diff --git a/ext/wasm/api/sqlite3-api-glue.c-pp.js b/ext/wasm/api/sqlite3-api-glue.c-pp.js
index ddcf2535f..bcaff7243 100644
--- a/ext/wasm/api/sqlite3-api-glue.c-pp.js
+++ b/ext/wasm/api/sqlite3-api-glue.c-pp.js
@@ -228,6 +228,31 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}),
'*'
]],
+ /**
+ 2025-02-03: We do not have a way to automatically clean up
+ destructors which are automatically converted from JS functions
+ via the final argument to sqlite3_set_auxdata(). Because of
+ that, it is strongly recommended that clients use
+ wasm.installFunction() to create such callbacks, then pass that
+ pointer to sqlite3_set_auxdata(). Relying on automated
+ conversions here will lead to leaks of JS/WASM proxy functions
+ because sqlite3_set_auxdata() is frequently called in UDFs.
+
+ The sqlite3.oo1.DB class's onclose handlers can be used for this
+ purpose. For example:
+
+ const pAuxDtor = wasm.installFunction('v(p)', function(ptr){
+ //free ptr
+ });
+ myDb.onclose = {
+ after: ()=>{
+ wasm.uninstallFunction(pAuxDtor);
+ }
+ };
+
+ Then pass pAuxDtor as the final argument to appropriate
+ sqlite3_set_auxdata() calls.
+ */
["sqlite3_set_auxdata", undefined, [
"sqlite3_context*", "int", "*",
new wasm.xWrap.FuncPtrAdapter({
@@ -1047,6 +1072,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
'sqlite3_set_authorizer',
'sqlite3_trace_v2',
'sqlite3_update_hook'
+ /*
+ We do not yet have a way to clean up automatically-converted
+ sqlite3_set_auxdata() finalizers.
+ */
]) {
const x = wasm.exports[name];
if( !x ){
diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js
index f83ecbd87..880edcec1 100644
--- a/ext/wasm/tester1.c-pp.js
+++ b/ext/wasm/tester1.c-pp.js
@@ -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*/;
////////////////////////////////////////////////////////////////////////