diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index a191668d5b..dafe430de0 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -586,3 +586,18 @@ push: $(wasm-testing.include) $(wasm-testing.dest) ssh wasm-testing 'cd $(wasm-testing.dir) && bash .gzip' || \ echo "SSH failed: it's likely that stale content will be served via old gzip files." + +WDOCS.home := $(wildcard ../../../wdoc) +ifneq (,$(WDOCS.home)) +WDOCS.jswasm += $(WDOCS.home)/jswasm +update-docs: + cp $(sqlite3.wasm) $(WDOCS.jswasm)/. + $(bin.stripccomments) -k -k < $(sqlite3.js) > $(WDOCS.jswasm)/sqlite3.js + cp demo-123.js demo-123.html demo-123-worker.html $(WDOCS.home) + sed -n -e '/EXTRACT_BEGIN/,/EXTRACT_END/p' \ + module-symbols.html > $(WDOCS.home)/module-symbols.html + +else +update-docs: + @echo "Cannot find wasm docs checkout." +endif diff --git a/ext/wasm/api/sqlite3-api-cleanup.js b/ext/wasm/api/sqlite3-api-cleanup.js index 555e5d31c5..bef4d91d70 100644 --- a/ext/wasm/api/sqlite3-api-cleanup.js +++ b/ext/wasm/api/sqlite3-api-cleanup.js @@ -59,7 +59,7 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build } /* Clean up temporary references to our APIs... */ - delete sqlite3.capi.util /* arguable, but these are (currently) internal-use APIs */; + delete sqlite3.util /* arguable, but these are (currently) internal-use APIs */; Module.sqlite3 = sqlite3 /* Needed for customized sqlite3InitModule() to be able to pass the sqlite3 object off to the client. */; }else{ diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 16840e79f3..63425e538c 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -20,8 +20,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ 'use strict'; const toss = (...args)=>{throw new Error(args.join(' '))}; const toss3 = sqlite3.SQLite3Error.toss; - const capi = sqlite3.capi, wasm = capi.wasm, util = capi.util; - self.WhWasmUtilInstaller(capi.wasm); + const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util; + self.WhWasmUtilInstaller(wasm); delete self.WhWasmUtilInstaller; /** @@ -88,7 +88,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ capi[e[0]] = wasm.xWrap.apply(null, e); } for(const e of wasm.bindingSignatures.wasm){ - capi.wasm[e[0]] = wasm.xWrap.apply(null, e); + wasm[e[0]] = wasm.xWrap.apply(null, e); } /* For C API functions which cannot work properly unless @@ -109,7 +109,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ delete wasm.bindingSignatures; if(wasm.exports.sqlite3_wasm_db_error){ - util.sqlite3_wasm_db_error = capi.wasm.xWrap( + util.sqlite3_wasm_db_error = wasm.xWrap( 'sqlite3_wasm_db_error', 'int', 'sqlite3*', 'int', 'string' ); }else{ @@ -176,7 +176,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } /* Wrap the callback in a WASM-bound function and convert the callback's `(char**)` arguments to arrays of strings... */ - const wasm = capi.wasm; const cbwrap = function(pVoid, nCols, pColVals, pColNames){ let rc = capi.SQLITE_ERROR; try { @@ -399,7 +398,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __dbArgcMismatch(pDb,"sqlite3_create_function_v2",f.length); } /* Wrap the callbacks in a WASM-bound functions... */ - const wasm = capi.wasm; const uninstall = [/*funcs to uninstall on error*/]; let rc; try{ @@ -441,7 +439,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __dbArgcMismatch(pDb,"sqlite3_create_window_function",f.length); } /* Wrap the callbacks in a WASM-bound functions... */ - const wasm = capi.wasm; const uninstall = [/*funcs to uninstall on error*/]; let rc; try{ diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index bab5a64ef2..cbdf40f9be 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -18,7 +18,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const toss = (...args)=>{throw new Error(args.join(' '))}; const toss3 = (...args)=>{throw new sqlite3.SQLite3Error(...args)}; - const capi = sqlite3.capi, wasm = capi.wasm, util = capi.util; + const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util; /* What follows is colloquially known as "OO API #1". It is a binding of the sqlite3 API which is designed to be run within the same thread (main or worker) as the one in which the @@ -694,7 +694,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ exec: function(/*(sql [,obj]) || (obj)*/){ affirmDbOpen(this); - const wasm = capi.wasm; const arg = parseExecArgs(arguments); if(!arg.sql){ return (''===arg.sql) ? this : toss3("exec() requires an SQL string."); @@ -925,7 +924,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const pApp = opt.pApp; if(undefined!==pApp && null!==pApp && - (('number'!==typeof pApp) || !capi.util.isInt32(pApp))){ + (('number'!==typeof pApp) || !util.isInt32(pApp))){ toss3("Invalid value for pApp property. Must be a legal WASM pointer value."); } const xDestroy = opt.xDestroy || 0; diff --git a/ext/wasm/api/sqlite3-api-opfs.js b/ext/wasm/api/sqlite3-api-opfs.js index 41efe0ab6d..a4516513cb 100644 --- a/ext/wasm/api/sqlite3-api-opfs.js +++ b/ext/wasm/api/sqlite3-api-opfs.js @@ -118,7 +118,7 @@ const installOpfsVfs = function callee(options){ const error = (...args)=>logImpl(0, ...args); const toss = function(...args){throw new Error(args.join(' '))}; const capi = sqlite3.capi; - const wasm = capi.wasm; + const wasm = sqlite3.wasm; const sqlite3_vfs = capi.sqlite3_vfs; const sqlite3_file = capi.sqlite3_file; const sqlite3_io_methods = capi.sqlite3_io_methods; @@ -924,7 +924,7 @@ const installOpfsVfs = function callee(options){ cannot add an after-initialize callback mechanism. */ opfsUtil.registerVfs = (asDefault=false)=>{ - return capi.wasm.exports.sqlite3_vfs_register( + return wasm.exports.sqlite3_vfs_register( opfsVfs.pointer, asDefault ? 1 : 0 ); }; diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index b841a0491d..6dae0b6060 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -557,110 +557,107 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( values. */ sqlite3_randomness: (n, outPtr)=>{/*installed later*/}, - - /** - Various internal-use utilities are added here as needed. They - are bound to an object only so that we have access to them in - the differently-scoped steps of the API bootstrapping - process. At the end of the API setup process, this object gets - removed. These are NOT part of the public API. - */ - util:{ - affirmBindableTypedArray, flexibleString, - bigIntFits32, bigIntFits64, bigIntFitsDouble, - isBindableTypedArray, - isInt32, isSQLableTypedArray, isTypedArray, - typedArrayToString, - isUIThread: ()=>'undefined'===typeof WorkerGlobalScope, - isSharedTypedArray, - typedArrayPart - }, - - /** - Holds state which are specific to the WASM-related - infrastructure and glue code. It is not expected that client - code will normally need these, but they're exposed here in case - it does. These APIs are _not_ to be considered an - official/stable part of the sqlite3 WASM API. They may change - as the developers' experience suggests appropriate changes. - - Note that a number of members of this object are injected - dynamically after the api object is fully constructed, so - not all are documented inline here. - */ - wasm: { - //^^^ TODO?: move wasm from sqlite3.capi.wasm to sqlite3.wasm - /** - Emscripten APIs have a deep-seated assumption that all pointers - are 32 bits. We'll remain optimistic that that won't always be - the case and will use this constant in places where we might - otherwise use a hard-coded 4. - */ - ptrSizeof: config.wasmPtrSizeof || 4, - /** - The WASM IR (Intermediate Representation) value for - pointer-type values. It MUST refer to a value type of the - size described by this.ptrSizeof _or_ it may be any value - which ends in '*', which Emscripten's glue code internally - translates to i32. - */ - ptrIR: config.wasmPtrIR || "i32", - /** - True if BigInt support was enabled via (e.g.) the - Emscripten -sWASM_BIGINT flag, else false. When - enabled, certain 64-bit sqlite3 APIs are enabled which - are not otherwise enabled due to JS/WASM int64 - impedence mismatches. - */ - bigIntEnabled: !!config.bigIntEnabled, - /** - The symbols exported by the WASM environment. - */ - exports: config.exports - || toss("Missing API config.exports (WASM module exports)."), - - /** - When Emscripten compiles with `-sIMPORT_MEMORY`, it - initalizes the heap and imports it into wasm, as opposed to - the other way around. In this case, the memory is not - available via this.exports.memory. - */ - memory: config.memory || config.exports['memory'] - || toss("API config object requires a WebAssembly.Memory object", - "in either config.exports.memory (exported)", - "or config.memory (imported)."), - - /** - The API's one single point of access to the WASM-side memory - allocator. Works like malloc(3) (and is likely bound to - malloc()) but throws an WasmAllocError if allocation fails. It is - important that any code which might pass through the sqlite3 C - API NOT throw and must instead return SQLITE_NOMEM (or - equivalent, depending on the context). - - That said, very few cases in the API can result in - client-defined functions propagating exceptions via the C-style - API. Most notably, this applies ot User-defined SQL Functions - (UDFs) registered via sqlite3_create_function_v2(). For that - specific case it is recommended that all UDF creation be - funneled through a utility function and that a wrapper function - be added around the UDF which catches any exception and sets - the error state to OOM. (The overall complexity of registering - UDFs essentially requires a helper for doing so!) - */ - alloc: undefined/*installed later*/, - /** - The API's one single point of access to the WASM-side memory - deallocator. Works like free(3) (and is likely bound to - free()). - */ - dealloc: undefined/*installed later*/ - - /* Many more wasm-related APIs get installed later on. */ - }/*wasm*/ }/*capi*/; - const wasm = capi.wasm, util = capi.util; + /** + Various internal-use utilities are added here as needed. They + are bound to an object only so that we have access to them in + the differently-scoped steps of the API bootstrapping + process. At the end of the API setup process, this object gets + removed. These are NOT part of the public API. + */ + const util = { + affirmBindableTypedArray, flexibleString, + bigIntFits32, bigIntFits64, bigIntFitsDouble, + isBindableTypedArray, + isInt32, isSQLableTypedArray, isTypedArray, + typedArrayToString, + isUIThread: ()=>'undefined'===typeof WorkerGlobalScope, + isSharedTypedArray, + typedArrayPart + }; + + /** + Holds state which are specific to the WASM-related + infrastructure and glue code. It is not expected that client + code will normally need these, but they're exposed here in case + it does. These APIs are _not_ to be considered an + official/stable part of the sqlite3 WASM API. They may change + as the developers' experience suggests appropriate changes. + + Note that a number of members of this object are injected + dynamically after the api object is fully constructed, so + not all are documented inline here. + */ + const wasm = { + /** + Emscripten APIs have a deep-seated assumption that all pointers + are 32 bits. We'll remain optimistic that that won't always be + the case and will use this constant in places where we might + otherwise use a hard-coded 4. + */ + ptrSizeof: config.wasmPtrSizeof || 4, + /** + The WASM IR (Intermediate Representation) value for + pointer-type values. It MUST refer to a value type of the + size described by this.ptrSizeof _or_ it may be any value + which ends in '*', which Emscripten's glue code internally + translates to i32. + */ + ptrIR: config.wasmPtrIR || "i32", + /** + True if BigInt support was enabled via (e.g.) the + Emscripten -sWASM_BIGINT flag, else false. When + enabled, certain 64-bit sqlite3 APIs are enabled which + are not otherwise enabled due to JS/WASM int64 + impedence mismatches. + */ + bigIntEnabled: !!config.bigIntEnabled, + /** + The symbols exported by the WASM environment. + */ + exports: config.exports + || toss("Missing API config.exports (WASM module exports)."), + + /** + When Emscripten compiles with `-sIMPORT_MEMORY`, it + initalizes the heap and imports it into wasm, as opposed to + the other way around. In this case, the memory is not + available via this.exports.memory. + */ + memory: config.memory || config.exports['memory'] + || toss("API config object requires a WebAssembly.Memory object", + "in either config.exports.memory (exported)", + "or config.memory (imported)."), + + /** + The API's one single point of access to the WASM-side memory + allocator. Works like malloc(3) (and is likely bound to + malloc()) but throws an WasmAllocError if allocation fails. It is + important that any code which might pass through the sqlite3 C + API NOT throw and must instead return SQLITE_NOMEM (or + equivalent, depending on the context). + + That said, very few cases in the API can result in + client-defined functions propagating exceptions via the C-style + API. Most notably, this applies ot User-defined SQL Functions + (UDFs) registered via sqlite3_create_function_v2(). For that + specific case it is recommended that all UDF creation be + funneled through a utility function and that a wrapper function + be added around the UDF which catches any exception and sets + the error state to OOM. (The overall complexity of registering + UDFs essentially requires a helper for doing so!) + */ + alloc: undefined/*installed later*/, + /** + The API's one single point of access to the WASM-side memory + deallocator. Works like free(3) (and is likely bound to + free()). + */ + dealloc: undefined/*installed later*/ + + /* Many more wasm-related APIs get installed later on. */ + }/*wasm*/; /** wasm.alloc()'s srcTypedArray.byteLength bytes, @@ -915,7 +912,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( /** Functions which are intended solely for API-internal use by the WASM components, not client code. These get installed into - capi.wasm. + sqlite3.wasm. */ wasm.bindingSignatures.wasm = [ ["sqlite3_wasm_db_reset", "int", "sqlite3*"], @@ -1127,7 +1124,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( } return ta; } - capi.wasm.exports.sqlite3_randomness(...args); + wasm.exports.sqlite3_randomness(...args); }; /** State for sqlite3_wasmfs_opfs_dir(). */ @@ -1304,7 +1301,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( : 0); }; - if( capi.util.isUIThread() ){ + if( util.isUIThread() ){ /* Features specific to the main window thread... */ /** @@ -1390,6 +1387,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( WasmAllocError: WasmAllocError, SQLite3Error: SQLite3Error, capi, + util, + wasm, config, /** Holds the version info of the sqlite3 source tree from which @@ -1489,7 +1488,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( this array is deleted. Note that the order of insertion into this array is significant for - some pieces. e.g. sqlite3.capi and sqlite3.capi.wasm cannot be fully + some pieces. e.g. sqlite3.capi and sqlite3.wasm cannot be fully utilized until the whwasmutil.js part is plugged in via sqlite3-api-glue.js. */ diff --git a/ext/wasm/api/sqlite3-api-worker1.js b/ext/wasm/api/sqlite3-api-worker1.js index 748ce4c6f5..1e8048159e 100644 --- a/ext/wasm/api/sqlite3-api-worker1.js +++ b/ext/wasm/api/sqlite3-api-worker1.js @@ -367,11 +367,11 @@ sqlite3.initWorker1API = function(){ if(db){ delete this.dbs[getDbId(db)]; const filename = db.filename; - const pVfs = sqlite3.capi.wasm.sqlite3_wasm_db_vfs(db.pointer, 0); + const pVfs = sqlite3.wasm.sqlite3_wasm_db_vfs(db.pointer, 0); db.close(); if(db===this.defaultDb) this.defaultDb = undefined; if(alsoUnlink && filename && pVfs){ - sqlite3.capi.wasm.sqlite3_wasm_vfs_unlink(pVfs, filename); + sqlite3.wasm.sqlite3_wasm_vfs_unlink(pVfs, filename); } } }, diff --git a/ext/wasm/api/sqlite3-worker1.js b/ext/wasm/api/sqlite3-worker1.js index 4cff68b08b..942437908f 100644 --- a/ext/wasm/api/sqlite3-worker1.js +++ b/ext/wasm/api/sqlite3-worker1.js @@ -30,8 +30,6 @@ - `sqlite3.dir`, if set, treats the given directory name as the directory from which `sqlite3.js` will be loaded. - - By default is loads 'sqlite3.js'. */ "use strict"; (()=>{ @@ -43,7 +41,9 @@ //console.warn("worker1 theJs =",theJs); importScripts(theJs); sqlite3InitModule().then((sqlite3)=>{ - sqlite3.capi.sqlite3_wasmfs_opfs_dir(); + if(sqlite3.capi.sqlite3_wasmfs_opfs_dir){ + sqlite3.capi.sqlite3_wasmfs_opfs_dir(); + } sqlite3.initWorker1API(); }); })(); diff --git a/ext/wasm/batch-runner.js b/ext/wasm/batch-runner.js index c40157bb59..11c43217ff 100644 --- a/ext/wasm/batch-runner.js +++ b/ext/wasm/batch-runner.js @@ -68,7 +68,7 @@ // This would be SO much easier with the oo1 API, but we specifically want to // inject metrics we can't get via that API, and we cannot reliably (OPFS) // open the same DB twice to clear it using that API, so... - const rc = sqlite3.capi.wasm.exports.sqlite3_wasm_db_reset(db.handle); + const rc = sqlite3.wasm.exports.sqlite3_wasm_db_reset(db.handle); App.logHtml("reset db rc =",rc,db.id, db.filename); }; @@ -115,7 +115,7 @@ const banner = "========================================"; this.logHtml(banner, "Running",name,'('+sql.length,'bytes) using',db.id); - const capi = this.sqlite3.capi, wasm = capi.wasm; + const capi = this.sqlite3.capi, wasm = this.sqlite3.wasm; let pStmt = 0, pSqlBegin; const stack = wasm.scopedAllocPush(); const metrics = db.metrics = Object.create(null); @@ -289,7 +289,7 @@ return; } if(!db.handle) return; - const capi = this.sqlite3, wasm = capi.wasm; + const capi = this.sqlite3, wasm = this.sqlite3.wasm; //const scope = wasm.scopedAllocPush( this.logErr("TODO: clear db"); }, @@ -488,7 +488,7 @@ App.logHtml(dbId,"cache_size =",cacheSize); }); }else{ - const capi = this.sqlite3.capi, wasm = capi.wasm; + const capi = this.sqlite3.capi, wasm = this.sqlite3.wasm; const stack = wasm.scopedAllocPush(); let pDb = 0; try{ @@ -516,7 +516,7 @@ run: function(sqlite3){ delete this.run; this.sqlite3 = sqlite3; - const capi = sqlite3.capi, wasm = capi.wasm; + const capi = sqlite3.capi, wasm = sqlite3.wasm; this.logHtml("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid()); this.logHtml("WASM heap size =",wasm.heap8().length); this.loadSqlList(); diff --git a/ext/wasm/demo-jsstorage.js b/ext/wasm/demo-jsstorage.js index 0621cb2dca..cf820e4033 100644 --- a/ext/wasm/demo-jsstorage.js +++ b/ext/wasm/demo-jsstorage.js @@ -44,7 +44,7 @@ const runTests = function(sqlite3){ const capi = sqlite3.capi, oo = sqlite3.oo1, - wasm = capi.wasm; + wasm = sqlite3.wasm; log("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid()); T.assert( 0 !== capi.sqlite3_vfs_find(null) ); if(!capi.sqlite3_vfs_find('kvvfs')){ diff --git a/ext/wasm/fiddle/fiddle-worker.js b/ext/wasm/fiddle/fiddle-worker.js index 935878c81a..a60b79ab2e 100644 --- a/ext/wasm/fiddle/fiddle-worker.js +++ b/ext/wasm/fiddle/fiddle-worker.js @@ -122,11 +122,11 @@ const Sqlite3Shell = { /** Returns the name of the currently-opened db. */ dbFilename: function f(){ - if(!f._) f._ = sqlite3.capi.wasm.xWrap('fiddle_db_filename', "string", ['string']); + if(!f._) f._ = sqlite3.wasm.xWrap('fiddle_db_filename', "string", ['string']); return f._(0); }, dbHandle: function f(){ - if(!f._) f._ = sqlite3.capi.wasm.xWrap("fiddle_db_handle", "sqlite3*"); + if(!f._) f._ = sqlite3.wasm.xWrap("fiddle_db_handle", "sqlite3*"); return f._(); }, dbIsOpfs: function f(){ @@ -145,7 +145,7 @@ that any argv strings passed to its main() are valid until the wasm environment shuts down. */ ]; - const capi = sqlite3.capi; + const capi = sqlite3.capi, wasm = sqlite3.wasm; /* We need to call sqlite3_shutdown() in order to avoid numerous legitimate warnings from the shell about it being initialized after sqlite3_initialize() has been called. This means, @@ -154,8 +154,8 @@ VFSes). We need a more generic approach to running such init-level code. */ capi.sqlite3_shutdown(); - f.argv.pArgv = capi.wasm.allocMainArgv(f.argv); - f.argv.rc = capi.wasm.exports.fiddle_main( + f.argv.pArgv = wasm.allocMainArgv(f.argv); + f.argv.rc = wasm.exports.fiddle_main( f.argv.length, f.argv.pArgv ); if(f.argv.rc){ @@ -187,7 +187,7 @@ exec: function f(sql){ if(!f._){ if(!this.runMain()) return; - f._ = sqlite3.capi.wasm.xWrap('fiddle_exec', null, ['string']); + f._ = sqlite3.wasm.xWrap('fiddle_exec', null, ['string']); } if(fiddleModule.isDead){ stderr("shell module has exit()ed. Cannot run SQL."); @@ -208,7 +208,7 @@ } }, resetDb: function f(){ - if(!f._) f._ = sqlite3.capi.wasm.xWrap('fiddle_reset_db', null); + if(!f._) f._ = sqlite3.wasm.xWrap('fiddle_reset_db', null); stdout("Resetting database."); f._(); stdout("Reset",this.dbFilename()); @@ -216,7 +216,7 @@ /* Interrupt can't work: this Worker is tied up working, so won't get the interrupt event which would be needed to perform the interrupt. */ interrupt: function f(){ - if(!f._) f._ = sqlite3.capi.wasm.xWrap('fiddle_interrupt', null); + if(!f._) f._ = sqlite3.wasm.xWrap('fiddle_interrupt', null); stdout("Requesting interrupt."); f._(); } @@ -370,9 +370,9 @@ */ sqlite3InitModule(fiddleModule).then((_sqlite3)=>{ sqlite3 = _sqlite3; - const dbVfs = sqlite3.capi.wasm.xWrap('fiddle_db_vfs', "*", ['string']); + const dbVfs = sqlite3.wasm.xWrap('fiddle_db_vfs', "*", ['string']); fiddleModule.fsUnlink = (fn)=>{ - return sqlite3.capi.wasm.sqlite3_wasm_vfs_unlink(dbVfs(0), fn); + return sqlite3.wasm.sqlite3_wasm_vfs_unlink(dbVfs(0), fn); }; wMsg('fiddle-ready'); })/*then()*/; diff --git a/ext/wasm/module-symbols.html b/ext/wasm/module-symbols.html index e77866a5e7..450abb9327 100644 --- a/ext/wasm/module-symbols.html +++ b/ext/wasm/module-symbols.html @@ -4,11 +4,17 @@ -