From 28ef9bddb3bdd823711d818d67ba16ae286c6c69 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 15 Sep 2022 06:42:41 +0000 Subject: [PATCH] More work on the synchronous OPFS experimentation. Numerous wasm/js build tweaks. Add speeedtest-wasmfs.html, the wasmfs/opfs counterpart of speedtest1.html. FossilOrigin-Name: 00ee49a3a2c148480f614e49a0ee5b35a255758c0a53693f0b464b31e7a4045b --- ext/wasm/EXPORTED_FUNCTIONS.fiddle | 2 - ext/wasm/GNUmakefile | 79 +++-- ext/wasm/api/sqlite3-api-oo1.js | 11 +- ext/wasm/api/sqlite3-api-prologue.js | 4 +- ext/wasm/api/sqlite3-wasm.c | 10 +- ext/wasm/index.html | 1 + ext/wasm/kvvfs.make | 10 +- ext/wasm/scratchpad-opfs-worker.js | 23 +- ext/wasm/scratchpad-opfs-worker2.js | 445 +++++++++++++++++++++++++-- ext/wasm/speedtest1-wasmfs.html | 159 ++++++++++ ext/wasm/speedtest1-worker.html | 16 +- ext/wasm/speedtest1-worker.js | 9 +- ext/wasm/speedtest1.html | 8 +- ext/wasm/wasmfs.make | 133 ++++---- manifest | 37 +-- manifest.uuid | 2 +- 16 files changed, 792 insertions(+), 157 deletions(-) create mode 100644 ext/wasm/speedtest1-wasmfs.html diff --git a/ext/wasm/EXPORTED_FUNCTIONS.fiddle b/ext/wasm/EXPORTED_FUNCTIONS.fiddle index 602d612548..b96ce4e67c 100644 --- a/ext/wasm/EXPORTED_FUNCTIONS.fiddle +++ b/ext/wasm/EXPORTED_FUNCTIONS.fiddle @@ -5,5 +5,3 @@ _fiddle_the_db _fiddle_db_arg _fiddle_db_filename _fiddle_reset_db -_sqlite3_wasm_init_opfs -_sqlite3_wasm_vfs_unlink diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 3e1bc90248..390472dea2 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -9,10 +9,11 @@ # components). SHELL := $(shell which bash 2>/dev/null) all: +emcc_opt ?= -O0 .PHONY: fiddle ifneq (,$(wildcard /home/stephan)) - fiddle_opt ?= -O0 + fiddle_opt ?= $(emcc_opt) else fiddle_opt = -Os endif @@ -61,7 +62,6 @@ SQLITE_OPT = \ # SQLITE_OMIT_LOAD_EXTENSION: if this is true, sqlite3_vfs::xDlOpen # and friends may be NULL. -emcc_opt ?= -O0 .PHONY: release release: $(MAKE) 'emcc_opt=-Os -g3 -flto' @@ -101,12 +101,12 @@ wasm-strip ?= $(shell which wasm-strip 2>/dev/null) ifeq (,$(filter clean,$(MAKECMDGOALS))) ifeq (,$(wasm-strip)) $(info WARNING: *******************************************************************) - $(info WARNING: builds using -O3/-Os/-Oz will minify WASM-exported names,) + $(info WARNING: builds using -O2/-O3/-Os/-Oz will minify WASM-exported names,) $(info WARNING: breaking _All The Things_. The workaround for that is to build) $(info WARNING: with -g3 (which explodes the file size) and then strip the debug) $(info WARNING: info after compilation, using wasm-strip, to shrink the wasm file.) $(info WARNING: wasm-strip was not found in the PATH so we cannot strip those.) - $(info WARNING: If this build uses any optimization level higher than -O2 then) + $(info WARNING: If this build uses any optimization level higher than -O1 then) $(info WARNING: the ***resulting WASM binary WILL NOT BE USABLE***.) $(info WARNING: wasm-strip is part of the wabt package:) $(info WARNING: https://github.com/WebAssembly/wabt) @@ -116,6 +116,13 @@ ifeq (,$(wasm-strip)) endif endif # 'make clean' check + +ifeq (,$(wasm-strip)) + maybe-wasm-strip = echo "not wasm-stripping" +else + maybe-wasm-strip = $(wasm-strip) +endif + ifeq (release,$(filter release,$(MAKECMDGOALS))) ifeq (,$(wasm-strip)) $(error Cannot make release-quality binary because wasm-strip is not available. \ @@ -286,9 +293,7 @@ $(sqlite3.js): $(MAKEFILE) $(sqlite3.wasm.obj) \ @echo "Building $@ ..." $(emcc.bin) -o $(sqlite3.js) $(emcc_opt) $(emcc.flags) $(emcc.jsflags) $(sqlite3.wasm.obj) chmod -x $(sqlite3.wasm) -ifneq (,$(wasm-strip)) - $(wasm-strip) $(sqlite3.wasm) -endif + $(maybe-wasm-strip) $(sqlite3.wasm) @ls -la $@ $(sqlite3.wasm) CLEAN_FILES += $(sqlite3.js) $(sqlite3.wasm) @@ -321,25 +326,28 @@ all: batch # end batch-runner.js ######################################################################## # speedtest1.js... -emcc.speedtest1-flags := -g $(emcc_opt) -emcc.speedtest1-flags += -sINVOKE_RUN=0 -#emcc.speedtest1-flags += --no-entry -emcc.speedtest1-flags += -flto -emcc.speedtest1-flags += -sABORTING_MALLOC -emcc.speedtest1-flags += -sINITIAL_MEMORY=128450560 -emcc.speedtest1-flags += -sSTRICT_JS -emcc.speedtest1-flags += $(emcc.environment) -emcc.speedtest1-flags += -sMODULARIZE -emcc.speedtest1-flags += -sEXPORT_NAME=sqlite3Speedtest1InitModule -emcc.speedtest1-flags += -Wno-limited-postlink-optimizations -emcc.speedtest1-flags += -sEXPORTED_FUNCTIONS=_main,_malloc,_free,_sqlite3_wasm_vfs_unlink,_sqlite3_wasm_init_opfs -emcc.speedtest1-flags += -sDYNAMIC_EXECUTION=0 -emcc.speedtest1-flags += --minify 0 +# speedtest1-common.eflags = emcc flags used by multiple builds of speedtest1 +# speedtest1.eflags = emcc flags used by main build of speedtest1 +speedtest1-common.eflags := -g $(emcc_opt) +speedtest1.eflags := +speedtest1-common.eflags += -sINVOKE_RUN=0 +#speedtest1-common.eflags += --no-entry +speedtest1-common.eflags += -flto +speedtest1-common.eflags += -sABORTING_MALLOC +speedtest1-common.eflags += -sINITIAL_MEMORY=128450560 +speedtest1-common.eflags += -sSTRICT_JS +speedtest1-common.eflags += -sMODULARIZE +speedtest1-common.eflags += -Wno-limited-postlink-optimizations +speedtest1-common.eflags += -sEXPORTED_FUNCTIONS=_main,_malloc,_free +speedtest1-common.eflags += -sDYNAMIC_EXECUTION=0 +speedtest1-common.eflags += --minify 0 +speedtest1-common.eflags += -sEXPORT_NAME=sqlite3Speedtest1InitModule +speedtest1.eflags += -sENVIRONMENT=web speedtest1.js := speedtest1.js speedtest1.wasm := $(subst .js,.wasm,$(speedtest1.js)) speedtest1.cflags := \ - -I. -I$(dir.top) \ + -I. -I.. -I$(dir.top) \ -DSQLITE_SPEEDTEST1_WASM $(speedtest1.js): emcc.cflags+= @@ -350,13 +358,11 @@ $(speedtest1.js): emcc.cflags+= $(speedtest1.js): $(speedtest1.c) $(sqlite3-wasm.c) $(MAKEFILE) $(sqlite3.c) @echo "Building $@ ..." $(emcc.bin) \ - $(emcc.speedtest1-flags) $(speedtest1.cflags) \ + $(speedtest1.eflags) $(speedtest1-common.eflags) $(speedtest1.cflags) \ $(SQLITE_OPT) \ '-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \ -o $@ $(speedtest1.c) $(sqlite3-wasm.c) -lm -ifneq (,$(wasm-strip)) - $(wasm-strip) $(speedtest1.wasm) -endif + $(maybe-wasm-strip) $(speedtest1.wasm) ls -la $@ $(speedtest1.wasm) speedtest1: $(speedtest1.js) @@ -388,5 +394,26 @@ push-fiddle: $(fiddle_files) # end fiddle remote push ######################################################################## +######################################################################## +# Convenience rules to rebuild with various -Ox levels. Much +# experimentation shows -O2 to be the clear winner in terms of speed. +# Note that build times with anything higher than -O0 are somewhat +# painful. +.PHONY: o0 o1 o2 o3 os oz +o0: + $(MAKE) clean; $(MAKE) -e emcc_opt=-O0 +o1: + $(MAKE) clean; $(MAKE) -e emcc_opt=-O1 +o2: + $(MAKE) clean; $(MAKE) -e emcc_opt=-O2 +o3: + $(MAKE) clean; $(MAKE) -e emcc_opt=-O3 +os: + $(MAKE) clean; $(MAKE) -e emcc_opt=-Os +oz: + $(MAKE) clean; $(MAKE) -e emcc_opt=-Oz + +######################################################################## +# Sub-makes... include kvvfs.make include wasmfs.make diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 6a8c229392..368986933f 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -1383,12 +1383,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return this.reset(); }, /** - Functions like step() except that - it finalizes this statement immediately after stepping unless - the step cannot be performed because the statement is - locked. Throws on error, but any error other than the - statement-is-locked case will also trigger finalization of this - statement. + Functions like step() except that it finalizes this statement + immediately after stepping unless the step cannot be performed + because the statement is locked. Throws on error, but any error + other than the statement-is-locked case will also trigger + finalization of this statement. On success, it returns true if the step indicated that a row of data was available, else it returns false. diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 1c22e9ea21..3d6d4c92b5 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -720,7 +720,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( } try{ if(pdir && 0===capi.wasm.xCallWrapped( - 'sqlite3_wasm_init_opfs', 'i32', ['string'], pdir + 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir )){ /** OPFS does not support locking and will trigger errors if we try to lock. We don't _really_ want to @@ -739,7 +739,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( return __persistentDir = ""; } }catch(e){ - // sqlite3_wasm_init_opfs() is not available + // sqlite3_wasm_init_wasmfs() is not available return __persistentDir = ""; } }; diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index c072e8c9d4..eb8f58b402 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -510,7 +510,7 @@ int sqlite3_wasm_vfs_unlink(const char * zName){ return rc; } -#if defined(__EMSCRIPTEN__) && defined(SQLITE_WASM_OPFS) +#if defined(__EMSCRIPTEN__) && defined(SQLITE_WASM_WASMFS) #include #include @@ -532,11 +532,11 @@ int sqlite3_wasm_vfs_unlink(const char * zName){ ** ** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend ** object fails, SQLITE_IOERR if mkdir() of the zMountPoint dir in -** the virtual FS fails. In builds compiled without SQLITE_WASM_OPFS +** the virtual FS fails. In builds compiled without SQLITE_WASM_WASMFS ** defined, SQLITE_NOTFOUND is returned without side effects. */ WASM_KEEP -int sqlite3_wasm_init_opfs(const char *zMountPoint){ +int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ static backend_t pOpfs = 0; if( !zMountPoint || !*zMountPoint ) zMountPoint = "/persistent"; if( !pOpfs ){ @@ -562,10 +562,10 @@ int sqlite3_wasm_init_opfs(const char *zMountPoint){ } #else WASM_KEEP -int sqlite3_wasm_init_opfs(void){ +int sqlite3_wasm_init_wasmfs(void){ return SQLITE_NOTFOUND; } -#endif /* __EMSCRIPTEN__ && SQLITE_WASM_OPFS */ +#endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */ #undef WASM_KEEP diff --git a/ext/wasm/index.html b/ext/wasm/index.html index 4b21839a4a..383045ea2c 100644 --- a/ext/wasm/index.html +++ b/ext/wasm/index.html @@ -39,6 +39,7 @@
  • batch-runner: runs batches of SQL exported from speedtest1.
  • speedtest1: a main-thread WASM build of speedtest1.
  • speedtest1-worker: an interactive Worker-thread variant of speedtest1.
  • +
  • speedtest1-wasmfs: a variant of speedtest1 built solely for the wasmfs/opfs feature.
  • speedtest1-kvvfs: a variant of speedtest1 built solely for the kv-vfs feature.
  • kvvfs1: very basic demo of using the key-value vfs for storing a persistent db in JS localStorage or sessionStorage.
  • diff --git a/ext/wasm/kvvfs.make b/ext/wasm/kvvfs.make index 3ef9dbddf9..293bcee04f 100644 --- a/ext/wasm/kvvfs.make +++ b/ext/wasm/kvvfs.make @@ -88,9 +88,7 @@ $(kvvfs.js): $(kvvfs.wasm.c) $(sqlite3.c) $(kvvfs.extra.c) \ $(SQLITE_OPT) \ $(kvvfs.cflags) $(kvvfs.jsflags) $(kvvfs.wasm.c) $(kvvfs.extra.c) chmod -x $(kvvfs.wasm) -ifneq (,$(wasm-strip)) - $(wasm-strip) $(kvvfs.wasm) -endif + $(maybe-wasm-strip) $(kvvfs.wasm) @ls -la $@ $(kvvfs.wasm) kvvfs: $(kvvfs.js) @@ -103,14 +101,12 @@ speedtest1-kvvfs.wasm := speedtest1-kvvfs.wasm CLEAN_FILES += $(speedtest1-kvvfs.js) $(speedtest1-kvvfs.wasm) $(speedtest1-kvvfs.js): $(speedtest1.c) $(sqlite3-wasm.c) $(sqlite3.c) $(MAKEFILE.kvvfs) $(emcc.bin) \ - $(emcc.speedtest1-flags) $(speedtest1.cflags) \ + $(speedtest1.eflags) $(speedtest1-common.eflags) $(speedtest1.cflags) \ $(SQLITE_OPT) \ -sEXIT_RUNTIME=1 \ $(kvvfs.cflags) \ -o $@ $(speedtest1.c) $(sqlite3-wasm.c) -lm -ifneq (,$(wasm-strip)) - $(wasm-strip) $(speedtest1-kvvfs.wasm) -endif + $(maybe-wasm-strip) $(speedtest1-kvvfs.wasm) ls -la $@ $(speedtest1-kvvfs.wasm) speedtest1: $(speedtest1-kvvfs.js) diff --git a/ext/wasm/scratchpad-opfs-worker.js b/ext/wasm/scratchpad-opfs-worker.js index debd0245e0..e27164775c 100644 --- a/ext/wasm/scratchpad-opfs-worker.js +++ b/ext/wasm/scratchpad-opfs-worker.js @@ -16,11 +16,26 @@ 'use strict'; (function(){ const toss = function(...args){throw new Error(args.join(' '))}; - const log = console.log.bind(console), - warn = console.warn.bind(console), - error = console.error.bind(console); + const eOutput = document.querySelector('#test-output'); + const logHtml = function(cssClass,...args){ + if(Array.isArray(args[0])) args = args[0]; + const ln = document.createElement('div'); + if(cssClass) ln.classList.add(cssClass); + ln.append(document.createTextNode(args.join(' '))); + eOutput.append(ln); + }; + const log = function(...args){ + logHtml('',...args); + }; + const error = function(...args){ + logHtml('error',...args); + }; + const warn = function(...args){ + logHtml('warning',...args); + }; + const W = new Worker("scratchpad-opfs-worker2.js"); - self.onmessage = function(ev){ + W.onmessage = function(ev){ ev = ev.data; const d = ev.data; switch(ev.type){ diff --git a/ext/wasm/scratchpad-opfs-worker2.js b/ext/wasm/scratchpad-opfs-worker2.js index 04b6bfc274..64e5266db2 100644 --- a/ext/wasm/scratchpad-opfs-worker2.js +++ b/ext/wasm/scratchpad-opfs-worker2.js @@ -16,25 +16,404 @@ is, quite frankly, broken). */ 'use strict'; -(function(){ - const toss = function(...args){throw new Error(args.join(' '))}; - importScripts('sqlite3.js'); + +const toss = function(...args){throw new Error(args.join(' '))}; +/** + Posts a message in the form {type,data} unless passed more than 2 + args, in which case it posts {type, data:[arg1...argN]}. +*/ +const wMsg = function(type,data){ + postMessage({ + type, + data: arguments.length<3 + ? data + : Array.prototype.slice.call(arguments,1) + }); +}; + +const stdout = function(...args){ + wMsg('stdout',args); + console.log(...args); +}; +const stderr = function(...args){ + wMsg('stderr',args); + console.error(...args); +}; + +const log = console.log.bind(console); +const warn = console.warn.bind(console); +const error = console.error.bind(console); + + +const initOpfsBits = async function(sqlite3){ + if(!self.importScripts || !self.FileSystemFileHandle){ + //|| !self.FileSystemFileHandle.prototype.createSyncAccessHandle){ + // ^^^ sync API is not required with WASMFS/OPFS backend. + warn("OPFS is not available in this environment."); + return; + }else if(!sqlite3.capi.wasm.bigIntEnabled){ + error("OPFS requires BigInt support but sqlite3.capi.wasm.bigIntEnabled is false."); + return; + } + //warn('self.FileSystemFileHandle =',self.FileSystemFileHandle); + //warn('self.FileSystemFileHandle.prototype =',self.FileSystemFileHandle.prototype); + const capi = sqlite3.capi, + wasm = capi.wasm; + const sqlite3_vfs = capi.sqlite3_vfs + || toss("Missing sqlite3.capi.sqlite3_vfs object."); + const sqlite3_file = capi.sqlite3_file + || toss("Missing sqlite3.capi.sqlite3_file object."); + const sqlite3_io_methods = capi.sqlite3_io_methods + || toss("Missing sqlite3.capi.sqlite3_io_methods object."); + const StructBinder = sqlite3.StructBinder || toss("Missing sqlite3.StructBinder."); + const debug = console.debug.bind(console), + log = console.log.bind(console); + warn("UNDER CONSTRUCTION: setting up OPFS VFS..."); + + const pDVfs = capi.sqlite3_vfs_find(null)/*pointer to default VFS*/; + const dVfs = pDVfs + ? new sqlite3_vfs(pDVfs) + : null /* dVfs will be null when sqlite3 is built with + SQLITE_OS_OTHER. Though we cannot currently handle + that case, the hope is to eventually be able to. */; + const oVfs = new sqlite3_vfs(); + const oIom = new sqlite3_io_methods(); + oVfs.$iVersion = 2/*yes, two*/; + oVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof; + oVfs.$mxPathname = 1024/*sure, why not?*/; + oVfs.$zName = wasm.allocCString("opfs"); + oVfs.ondispose = [ + '$zName', oVfs.$zName, + 'cleanup dVfs', ()=>(dVfs ? dVfs.dispose() : null) + ]; + if(dVfs){ + oVfs.$xSleep = dVfs.$xSleep; + oVfs.$xRandomness = dVfs.$xRandomness; + } + // All C-side memory of oVfs is zeroed out, but just to be explicit: + oVfs.$xDlOpen = oVfs.$xDlError = oVfs.$xDlSym = oVfs.$xDlClose = null; /** - Posts a message in the form {type,data} unless passed more than 2 - args, in which case it posts {type, data:[arg1...argN]}. + Pedantic sidebar about oVfs.ondispose: the entries in that array + are items to clean up when oVfs.dispose() is called, but in this + environment it will never be called. The VFS instance simply + hangs around until the WASM module instance is cleaned up. We + "could" _hypothetically_ clean it up by "importing" an + sqlite3_os_end() impl into the wasm build, but the shutdown order + of the wasm engine and the JS one are undefined so there is no + guaranty that the oVfs instance would be available in one + environment or the other when sqlite3_os_end() is called (_if_ it + gets called at all in a wasm build, which is undefined). */ - const wMsg = function(type,data){ - postMessage({ - type, - data: arguments.length<3 - ? data - : Array.prototype.slice.call(arguments,1) - }); + + /** + Installs a StructBinder-bound function pointer member of the + given name and function in the given StructType target object. + It creates a WASM proxy for the given function and arranges for + that proxy to be cleaned up when tgt.dispose() is called. Throws + on the slightest hint of error (e.g. tgt is-not-a StructType, + name does not map to a struct-bound member, etc.). + + Returns a proxy for this function which is bound to tgt and takes + 2 args (name,func). That function returns the same thing, + permitting calls to be chained. + + If called with only 1 arg, it has no side effects but returns a + func with the same signature as described above. + */ + const installMethod = function callee(tgt, name, func){ + if(!(tgt instanceof StructBinder.StructType)){ + toss("Usage error: target object is-not-a StructType."); + } + if(1===arguments.length){ + return (n,f)=>callee(tgt,n,f); + } + if(!callee.argcProxy){ + callee.argcProxy = function(func,sig){ + return function(...args){ + if(func.length!==arguments.length){ + toss("Argument mismatch. Native signature is:",sig); + } + return func.apply(this, args); + } + }; + callee.removeFuncList = function(){ + if(this.ondispose.__removeFuncList){ + this.ondispose.__removeFuncList.forEach( + (v,ndx)=>{ + if('number'===typeof v){ + try{wasm.uninstallFunction(v)} + catch(e){/*ignore*/} + } + /* else it's a descriptive label for the next number in + the list. */ + } + ); + delete this.ondispose.__removeFuncList; + } + }; + }/*static init*/ + const sigN = tgt.memberSignature(name); + if(sigN.length<2){ + toss("Member",name," is not a function pointer. Signature =",sigN); + } + const memKey = tgt.memberKey(name); + //log("installMethod",tgt, name, sigN); + const fProxy = 1 + // We can remove this proxy middle-man once the VFS is working + ? callee.argcProxy(func, sigN) + : func; + const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true)); + tgt[memKey] = pFunc; + if(!tgt.ondispose) tgt.ondispose = []; + if(!tgt.ondispose.__removeFuncList){ + tgt.ondispose.push('ondispose.__removeFuncList handler', + callee.removeFuncList); + tgt.ondispose.__removeFuncList = []; + } + tgt.ondispose.__removeFuncList.push(memKey, pFunc); + return (n,f)=>callee(tgt, n, f); + }/*installMethod*/; + + /** + Map of sqlite3_file pointers to OPFS handles. + */ + const __opfsHandles = Object.create(null); + + /** + Generates a random ASCII string len characters long, intended for + use as a temporary file name. + */ + const randomFilename = function f(len=16){ + if(!f._chars){ + f._chars = "abcdefghijklmnopqrstuvwxyz"+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ + "012346789"; + f._n = f._chars.length; + } + const a = []; + let i = 0; + for( ; i < len; ++i){ + const ndx = Math.random() * (f._n * 64) % f._n | 0; + a[i] = f._chars[ndx]; + } + return a.join(''); }; - const stdout = console.log.bind(console); - const stderr = console.error.bind(console);//function(...args){wMsg('stderr', args);}; + const rootDir = await navigator.storage.getDirectory(); + log("rootDir =",rootDir); + + //////////////////////////////////////////////////////////////////////// + // Set up OPFS VFS methods... + let inst = installMethod(oVfs); + inst('xOpen', function(pVfs, zName, pFile, flags, pOutFlags){ + const f = new sqlite3_file(pFile); + f.$pMethods = oIom.pointer; + __opfsHandles[pFile] = f; + f.opfsHandle = null /* TODO */; + if(flags & capi.SQLITE_OPEN_DELETEONCLOSE){ + f.deleteOnClose = true; + } + f.filename = zName ? wasm.cstringToJs(zName) : 'sqlite3-xOpen-'+randomFilename(); + error("OPFS sqlite3_vfs::xOpen is not yet full implemented."); + return capi.SQLITE_IOERR; + }) + ('xFullPathname', function(pVfs,zName,nOut,pOut){ + /* Until/unless we have some notion of "current dir" + in OPFS, simply copy zName to pOut... */ + const i = wasm.cstrncpy(pOut, zName, nOut); + return i remove() + return capi.SQLITE_IOERR; + }) + ('xGetLastError', function(pVfs,nOut,pOut){ + debug("OPFS sqlite3_vfs::xGetLastError() has nothing sensible to return."); + return 0; + }) + ('xCurrentTime', function(pVfs,pOut){ + /* If it turns out that we need to adjust for timezone, see: + https://stackoverflow.com/a/11760121/1458521 */ + wasm.setMemValue(pOut, 2440587.5 + (new Date().getTime()/86400000), + 'double'); + return 0; + }) + ('xCurrentTimeInt64',function(pVfs,pOut){ + // TODO: confirm that this calculation is correct + wasm.setMemValue(pOut, (2440587.5 * 86400000) + new Date().getTime(), + 'i64'); + return 0; + }); + if(!oVfs.$xSleep){ + inst('xSleep', function(pVfs,ms){ + error("sqlite3_vfs::xSleep(",ms,") cannot be implemented from "+ + "JS and we have no default VFS to copy the impl from."); + return 0; + }); + } + if(!oVfs.$xRandomness){ + inst('xRandomness', function(pVfs, nOut, pOut){ + const heap = wasm.heap8u(); + let i = 0; + for(; i < nOut; ++i) heap[pOut + i] = (Math.random()*255000) & 0xFF; + return i; + }); + } + + //////////////////////////////////////////////////////////////////////// + // Set up OPFS sqlite3_io_methods... + inst = installMethod(oIom); + inst('xClose', async function(pFile){ + warn("xClose(",arguments,") uses await"); + const f = __opfsHandles[pFile]; + delete __opfsHandles[pFile]; + if(f.opfsHandle){ + await f.opfsHandle.close(); + if(f.deleteOnClose){ + // TODO + } + } + f.dispose(); + return 0; + }) + ('xRead', /*i(ppij)*/function(pFile,pDest,n,offset){ + /* int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst) */ + try { + const f = __opfsHandles[pFile]; + const heap = wasm.heap8u(); + const b = new Uint8Array(heap.buffer, pDest, n); + const nRead = f.opfsHandle.read(b, {at: offset}); + if(nRead SQLITE_DEFAULT_SECTOR_SIZE */; + //}) + + const rc = capi.sqlite3_vfs_register(oVfs.pointer, 0); + if(rc){ + oVfs.dispose(); + toss("sqlite3_vfs_register(OPFS) failed with rc",rc); + } + capi.sqlite3_vfs_register.addReference(oVfs, oIom); + warn("End of (very incomplete) OPFS setup.", oVfs); + //oVfs.dispose()/*only because we can't yet do anything with it*/; + +}/*initOpfsBits()*/; + +(async function(){ + importScripts('sqlite3.js'); const test1 = function(db){ db.exec("create table if not exists t(a);") @@ -47,7 +426,7 @@ }); }; - const runTests = function(Module){ + const runTests = async function(Module){ //stdout("Module",Module); self._MODULE = Module /* this is only to facilitate testing from the console */; const sqlite3 = Module.sqlite3, @@ -55,11 +434,39 @@ oo = sqlite3.oo1, wasm = capi.wasm; stdout("Loaded sqlite3:",capi.sqlite3_libversion(), capi.sqlite3_sourceid()); - const persistentDir = capi.sqlite3_web_persistent_dir(); - if(persistentDir){ - stderr("Persistent storage dir:",persistentDir); + + if(1){ + let errCount = 0; + [ + 'FileSystemHandle', 'FileSystemFileHandle', 'FileSystemDirectoryHandle', + 'FileSystemHandle', 'FileSystemFileHandle', 'FileSystemDirectoryHandle' + ].forEach(function(n){ + const f = self[n]; + if(f){ + warn(n,f); + warn(n+'.prototype',f.prototype); + }else{ + stderr("MISSING",n); + ++errCount; + } + }); + if(errCount) return; + } + await initOpfsBits(sqlite3); + + if(1) return; + + let persistentDir; + if(1){ + persistentDir = ''; }else{ - stderr("No persistent storage available."); + persistentDir = capi.sqlite3_web_persistent_dir(); + if(persistentDir){ + stderr("Persistent storage dir:",persistentDir); + }else{ + stderr("No persistent storage available."); + return; + } } const startTime = performance.now(); let db; diff --git a/ext/wasm/speedtest1-wasmfs.html b/ext/wasm/speedtest1-wasmfs.html new file mode 100644 index 0000000000..151ced89a3 --- /dev/null +++ b/ext/wasm/speedtest1-wasmfs.html @@ -0,0 +1,159 @@ + + + + + + + + + speedtest1-wasmfs.wasm + + +
    speedtest1-wasmfs.wasm
    + + +
    +
    +
    Initializing app...
    +
    + On a slow internet connection this may take a moment. If this + message displays for "a long time", intialization may have + failed and the JavaScript console may contain clues as to why. +
    +
    +
    Downloading...
    +
    + +
    +
    This page starts running the main exe when it loads, which will + block the UI until it finishes! Adding UI controls to manually configure and start it + are TODO.
    + +
    Achtung: running it with the dev tools open may + drastically slow it down. For faster results, keep the dev + tools closed when running it! +
    +
    Output is delayed/buffered because we cannot update the UI while the + speedtest is running. Output will appear below when ready... +
    + + + + + + diff --git a/ext/wasm/speedtest1-worker.html b/ext/wasm/speedtest1-worker.html index ba74d9f7c6..0e0ca4c464 100644 --- a/ext/wasm/speedtest1-worker.html +++ b/ext/wasm/speedtest1-worker.html @@ -34,9 +34,14 @@
    @@ -167,6 +172,7 @@ const eFlags = E('#select-flags'); const eSelectedFlags = E('#toolbar-selected-flags'); const eLinkMainThread = E('#link-main-thread'); + const eLinkWasmfs = E('#link-wasmfs'); const getSelectedFlags = ()=>Array.prototype.map.call(eFlags.selectedOptions, (v)=>v.value); const updateSelectedFlags = function(){ eSelectedFlags.innerText = ''; @@ -178,8 +184,10 @@ }); const rxStripDash = /^(-+)?/; const comma = flags.map((v)=>v.replace(rxStripDash,'')).join(','); - eLinkMainThread.setAttribute('target', 'main-thread-'+comma); + eLinkMainThread.setAttribute('target', 'speedtest1-main-'+comma); eLinkMainThread.href = 'speedtest1.html?flags='+comma; + eLinkWasmfs.setAttribute('target', 'speedtest1-wasmfs-'+comma); + eLinkWasmfs.href = 'speedtest1-wasmfs.html?flags='+comma; }; eFlags.addEventListener('change', updateSelectedFlags ); { diff --git a/ext/wasm/speedtest1-worker.js b/ext/wasm/speedtest1-worker.js index 8512bdbbf7..b954f9939a 100644 --- a/ext/wasm/speedtest1-worker.js +++ b/ext/wasm/speedtest1-worker.js @@ -16,14 +16,14 @@ } try{ if(0===wasmUtil.xCallWrapped( - 'sqlite3_wasm_init_opfs', 'i32', ['string'], pdir + 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir )){ return f._ = pdir; }else{ return f._ = ""; } }catch(e){ - // sqlite3_wasm_init_opfs() is not available + // sqlite3_wasm_init_wasmfs() is not available return f._ = ""; } }; @@ -91,9 +91,8 @@ self.WhWasmUtilInstaller(App.wasm); App.unlink = App.wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["string"]); App.pDir = opfsDir(App.wasm); - if(App.pDir){ - log("Persistent storage:",pDir); - } + if(App.pDir) log("Persistent storage:",pDir); + else log("Using transient storage."); mPost('ready',true); }); })(); diff --git a/ext/wasm/speedtest1.html b/ext/wasm/speedtest1.html index bc8b4ec9f1..172266aa68 100644 --- a/ext/wasm/speedtest1.html +++ b/ext/wasm/speedtest1.html @@ -55,14 +55,14 @@ } try{ if(0===wasmUtil.xCallWrapped( - 'sqlite3_wasm_init_opfs', 'i32', ['string'], pdir + 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir )){ return f._ = pdir; }else{ return f._ = ""; } }catch(e){ - // sqlite3_wasm_init_opfs() is not available + // sqlite3_wasm_init_wasmfs() is not available return f._ = ""; } }; @@ -122,9 +122,9 @@ "--nomemstat" ); //"--memdb", // note that memdb trumps the filename arg - argv.push("--big-transactions"/*important for tests 410 and 510!*/, - dbFile); } + argv.push("--big-transactions"/*important for tests 410 and 510!*/, + dbFile); console.log("argv =",argv); // These log messages are not emitted to the UI until after main() returns. Fixing that // requires moving the main() call and related cleanup into a timeout handler. diff --git a/ext/wasm/wasmfs.make b/ext/wasm/wasmfs.make index f69da43b9e..cc10e58877 100644 --- a/ext/wasm/wasmfs.make +++ b/ext/wasm/wasmfs.make @@ -7,89 +7,114 @@ ######################################################################## MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST)) -wasmfs.js := sqlite3-wasmfs.js -wasmfs.wasm := sqlite3-wasmfs.wasm -wasmfs.wasm.c := $(dir.api)/sqlite3-wasm.c +sqlite3-wasmfs.js := sqlite3-wasmfs.js +sqlite3-wasmfs.wasm := sqlite3-wasmfs.wasm +sqlite3-wasmfs.wasm.c := $(dir.api)/sqlite3-wasm.c -CLEAN_FILES += $(wasmfs.js) $(wasmfs.wasm) +CLEAN_FILES += $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.wasm) \ + $(subst .js,.worker.js,$(sqlite3-wasmfs.js)) ######################################################################## # emcc flags for .c/.o/.wasm. -wasmfs.flags = -#wasmfs.flags += -v # _very_ loud but also informative about what it's doing +sqlite3-wasmfs.flags = +#sqlite3-wasmfs.flags += -v # _very_ loud but also informative about what it's doing ######################################################################## # emcc flags for .c/.o. -wasmfs.cflags := -wasmfs.cflags += -std=c99 -fPIC -g -wasmfs.cflags += -pthread -wasmfs.cflags += -I. -I$(dir.top) -wasmfs.cflags += $(SQLITE_OPT) -DSQLITE_WASM_OPFS -wasmfs.cflags += '-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' +sqlite3-wasmfs.cflags := +sqlite3-wasmfs.cflags += -std=c99 -fPIC -g +sqlite3-wasmfs.cflags += -pthread +sqlite3-wasmfs.cflags += -I. -I.. -I$(dir.top) +sqlite3-wasmfs.cflags += $(SQLITE_OPT) -DSQLITE_WASM_WASMFS +sqlite3-wasmfs.cflags += '-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' -wasmfs.extra.c := +sqlite3-wasmfs.extra.c := ifeq (1,1) - # To get testing1.js to run with $(wasmfs.js) we need... - wasmfs.extra.c += $(jaccwabyt_test.c) + # To get testing1.js to run with $(sqlite3-wasmfs.js) we need... + sqlite3-wasmfs.extra.c += $(jaccwabyt_test.c) endif ######################################################################## # emcc flags specific to building the final .js/.wasm file... -wasmfs.jsflags := -fPIC -wasmfs.jsflags += --no-entry -wasmfs.jsflags += --minify 0 -wasmfs.jsflags += -sENVIRONMENT=web,worker -wasmfs.jsflags += -sMODULARIZE -wasmfs.jsflags += -sSTRICT_JS -wasmfs.jsflags += -sDYNAMIC_EXECUTION=0 -wasmfs.jsflags += -sNO_POLYFILL -ifeq (,$(wasmfs.extra.c)) - wasmfs.jsflags += -sEXPORTED_FUNCTIONS=@$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api +sqlite3-wasmfs.jsflags := -fPIC +sqlite3-wasmfs.jsflags += --no-entry +sqlite3-wasmfs.jsflags += --minify 0 +sqlite3-wasmfs.jsflags += -sMODULARIZE +sqlite3-wasmfs.jsflags += -sSTRICT_JS +sqlite3-wasmfs.jsflags += -sDYNAMIC_EXECUTION=0 +sqlite3-wasmfs.jsflags += -sNO_POLYFILL +ifeq (,$(sqlite3-wasmfs.extra.c)) + sqlite3-wasmfs.jsflags += -sEXPORTED_FUNCTIONS=@$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api else # need more exports for jaccwabyt test code... - wasmfs.jsflags += -sEXPORTED_FUNCTIONS=@$(dir.wasm)/EXPORTED_FUNCTIONS.api + sqlite3-wasmfs.jsflags += -sEXPORTED_FUNCTIONS=@$(dir.wasm)/EXPORTED_FUNCTIONS.api endif -wasmfs.jsflags += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory,allocateUTF8OnStack +sqlite3-wasmfs.jsflags += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory,allocateUTF8OnStack # wasmMemory ==> for -sIMPORTED_MEMORY # allocateUTF8OnStack ==> wasmfs internals -wasmfs.jsflags += -sUSE_CLOSURE_COMPILER=0 -wasmfs.jsflags += -sIMPORTED_MEMORY -#wasmfs.jsflags += -sINITIAL_MEMORY=13107200 -#wasmfs.jsflags += -sTOTAL_STACK=4194304 -wasmfs.jsflags += -sEXPORT_NAME=sqlite3InitModule -wasmfs.jsflags += -sGLOBAL_BASE=4096 # HYPOTHETICALLY keep func table indexes from overlapping w/ heap addr. -wasmfs.jsflags += --post-js=$(post-js.js) -#wasmfs.jsflags += -sFILESYSTEM=0 # only for experimentation. sqlite3 needs the FS API +sqlite3-wasmfs.jsflags += -sUSE_CLOSURE_COMPILER=0 +sqlite3-wasmfs.jsflags += -sIMPORTED_MEMORY +#sqlite3-wasmfs.jsflags += -sINITIAL_MEMORY=13107200 +#sqlite3-wasmfs.jsflags += -sTOTAL_STACK=4194304 +sqlite3-wasmfs.jsflags += -sEXPORT_NAME=sqlite3InitModule +sqlite3-wasmfs.jsflags += -sGLOBAL_BASE=4096 # HYPOTHETICALLY keep func table indexes from overlapping w/ heap addr. +sqlite3-wasmfs.jsflags += --post-js=$(post-js.js) +#sqlite3-wasmfs.jsflags += -sFILESYSTEM=0 # only for experimentation. sqlite3 needs the FS API # Perhaps the wasmfs build doesn't? -#wasmfs.jsflags += -sABORTING_MALLOC -wasmfs.jsflags += -sALLOW_TABLE_GROWTH -wasmfs.jsflags += -Wno-limited-postlink-optimizations +#sqlite3-wasmfs.jsflags += -sABORTING_MALLOC +sqlite3-wasmfs.jsflags += -sALLOW_TABLE_GROWTH +sqlite3-wasmfs.jsflags += -Wno-limited-postlink-optimizations # ^^^^^ it likes to warn when we have "limited optimizations" via the -g3 flag. -wasmfs.jsflags += -sERROR_ON_UNDEFINED_SYMBOLS=0 -wasmfs.jsflags += -sLLD_REPORT_UNDEFINED -#wasmfs.jsflags += --import-undefined -wasmfs.jsflags += -sMEMORY64=0 -wasmfs.jsflags += -pthread -sWASMFS -sPTHREAD_POOL_SIZE=2 -wasmfs.jsflags += -sINITIAL_MEMORY=128450560 -#wasmfs.jsflags += -sALLOW_MEMORY_GROWTH +sqlite3-wasmfs.jsflags += -sERROR_ON_UNDEFINED_SYMBOLS=0 +sqlite3-wasmfs.jsflags += -sLLD_REPORT_UNDEFINED +#sqlite3-wasmfs.jsflags += --import-undefined +sqlite3-wasmfs.jsflags += -sMEMORY64=0 +sqlite3-wasmfs.jsflags += -sINITIAL_MEMORY=128450560 +sqlite3-wasmfs.fsflags := -pthread -sWASMFS -sPTHREAD_POOL_SIZE=2 -sENVIRONMENT=web,worker +sqlite3-wasmfs.jsflags += $(sqlite3-wasmfs.fsflags) +#sqlite3-wasmfs.jsflags += -sALLOW_MEMORY_GROWTH #^^^ using ALLOW_MEMORY_GROWTH produces a warning from emcc: # USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly, # see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth] ifneq (0,$(enable_bigint)) -wasmfs.jsflags += -sWASM_BIGINT +sqlite3-wasmfs.jsflags += -sWASM_BIGINT endif -$(wasmfs.js): $(wasmfs.wasm.c) $(sqlite3.c) $(wasmfs.extra.c) \ +$(sqlite3-wasmfs.js): $(sqlite3-wasmfs.wasm.c) $(sqlite3.c) $(sqlite3-wasmfs.extra.c) \ EXPORTED_FUNCTIONS.api $(MAKEFILE) $(MAKEFILE.wasmfs) \ $(post-js.js) @echo "Building $@ ..." $(emcc.bin) -o $@ $(emcc_opt) $(emcc.flags) \ - $(wasmfs.cflags) $(wasmfs.jsflags) $(wasmfs.wasm.c) $(wasmfs.extra.c) - chmod -x $(wasmfs.wasm) -ifneq (,$(wasm-strip)) - $(wasm-strip) $(wasmfs.wasm) -endif - @ls -la $@ $(wasmfs.wasm) + $(sqlite3-wasmfs.cflags) $(sqlite3-wasmfs.jsflags) $(sqlite3-wasmfs.wasm.c) $(sqlite3-wasmfs.extra.c) + chmod -x $(sqlite3-wasmfs.wasm) + $(maybe-wasm-strip) $(sqlite3-wasmfs.wasm) + @ls -la $@ $(sqlite3-wasmfs.wasm) -wasmfs: $(wasmfs.js) +wasmfs: $(sqlite3-wasmfs.js) all: wasmfs + +######################################################################## +# speedtest1 for wasmfs. Re. sqlite3-wasm.o vs sqlite3-wasm.c: +# building against the latter (predictably) results in a slightly +# faster binary. +speedtest1-wasmfs.js := speedtest1-wasmfs.js +speedtest1-wasmfs.wasm := $(subst .js,.wasm,$(speedtest1-wasmfs.js)) +speedtest1-wasmfs.eflags := -sENVIRONMENT=web,worker $(sqlite3-wasmfs.fsflags) +speedtest1-wasmfs.eflags += $(SQLITE_OPT) -DSQLITE_WASM_WASMFS +$(speedtest1-wasmfs.js): $(MAKEFILE) $(MAKEFILE.wasmfs) +#$(speedtest1-wasmfs.js): $(sqlite3-wasmfs.js) +$(speedtest1-wasmfs.js): $(speedtest1.c) $(sqlite3-wasm.c) + @echo "Building $@ ..." + $(emcc.bin) \ + $(speedtest1-wasmfs.eflags) $(speedtest1-common.eflags) \ + $(speedtest1.cflags) \ + $(sqlite3-wasmfs.cflags) \ + -o $@ $(speedtest1.c) $(sqlite3-wasm.c) -lm + $(maybe-wasm-strip) $(speedtest1-wasmfs.wasm) + ls -la $@ $(speedtest1-wasmfs.wasm) + +speedtest1: $(speedtest1-wasmfs.js) +CLEAN_FILES += $(speedtest1-wasmfs.js) $(speedtest1-wasmfs.wasm) \ + $(subst .js,.worker.js,$(speedtest1-wasmfs.js)) +# end speedtest1.js +######################################################################## diff --git a/manifest b/manifest index 543bbdbf9a..68aabcc46a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sstale\scomments.\sGet\sscratchpad-opfs-worker2.js\srunning\sagain\sin\sprep\sfor\sreuse\sin\sexperimenting\swith\sthe\sOPFS\sall-synchronous\sAPI. -D 2022-09-15T03:16:49.402 +C More\swork\son\sthe\ssynchronous\sOPFS\sexperimentation.\sNumerous\swasm/js\sbuild\stweaks.\sAdd\sspeeedtest-wasmfs.html,\sthe\swasmfs/opfs\scounterpart\sof\sspeedtest1.html. +D 2022-09-15T06:42:41.192 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -472,9 +472,9 @@ F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb -F ext/wasm/EXPORTED_FUNCTIONS.fiddle db7a4602f043cf4a5e4135be3609a487f9f1c83f05778bfbdf93766be4541b96 +F ext/wasm/EXPORTED_FUNCTIONS.fiddle 7fb73f7150ab79d83bb45a67d257553c905c78cd3d693101699243f36c5ae6c3 F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02 -F ext/wasm/GNUmakefile f06963ecf1a8275755a568f84ad66e1c6a093e190cffd84f1414d8e75d3c5277 +F ext/wasm/GNUmakefile 104ad527fd7cf1b33dd8ac544c4e26c529c305e591d85a32999258750998b0b8 F ext/wasm/README.md e1ee1e7c321c6a250bf78a84ca6f5882890a237a450ba5a0649c7a8399194c52 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 150a793a47205b8009ac934f3b6d6ebf67b965c072339aaa25ce808a19e116cc F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 @@ -483,12 +483,12 @@ F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba814 F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b F ext/wasm/api/sqlite3-api-cleanup.js 8564a6077cdcaea9a9f428a019af8a05887f0131e6a2a1e72a7ff1145fadfe77 F ext/wasm/api/sqlite3-api-glue.js 366d580c8e5bf7fcf4c6dee6f646c31f5549bd417ea03a59a0acca00e8ecce30 -F ext/wasm/api/sqlite3-api-oo1.js 8a8e464c2c786f4faa3fd5b48852818dd2938c3211d82b6176143990a976f8ec +F ext/wasm/api/sqlite3-api-oo1.js d7526517f7ad3f6bda16ad66d373bbb71b43168deef7af60eda5c9fe873d1387 F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0 -F ext/wasm/api/sqlite3-api-prologue.js c496adc0cf2ae427ee900aad01c09db97850bd8b6737f2849cab207c8415b839 +F ext/wasm/api/sqlite3-api-prologue.js 7aff2d9b110d5a6e70dbf5fe44189d983d7886a465ad156176f4ad290447c97b F ext/wasm/api/sqlite3-api-worker1.js d33062afa045fd4be01ba4abc266801807472558b862b30056211b00c9c347b4 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 7d1760f3a864a9ae16cfb71543829d946a54384bd07af99a3adf9ef32913705f +F ext/wasm/api/sqlite3-wasm.c 4130e2df9587f4e4c3afc04c3549d682c8a5c0cfe5b22819a0a86edb7f01b9bd F ext/wasm/batch-runner.html 2857a6db7292ac83d1581af865d643fd34235db2df830d10b43b01388c599e04 F ext/wasm/batch-runner.js fb6a338aeef509f181f499700a8595bc578bbc54ef832e0cda7e7e7c10b90a18 F ext/wasm/common/SqliteTestUtil.js 529161a624265ba84271a52db58da022649832fa1c71309fb1e02cc037327a2b @@ -501,23 +501,24 @@ F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d695 F ext/wasm/fiddle/fiddle-worker.js bccf46045be8824752876f3eec01c223be0616ccac184bffd0024cfe7a3262b8 F ext/wasm/fiddle/fiddle.html 550c5aafce40bd218de9bf26192749f69f9b10bc379423ecd2e162bcef885c08 F ext/wasm/fiddle/fiddle.js 4ffcfc9a235beebaddec689a549e9e0dfad6dca5c1f0b41f03468d7e76480686 -F ext/wasm/index.html 7e38070c8c64738eb3893be19e1291d66629fc424f1a70e12c4b459d51dbeffe +F ext/wasm/index.html e251800a64cf13e731ddec5a86ca4a299dcc4c1fafafd87658ccca3c538dd843 F ext/wasm/jaccwabyt/jaccwabyt.js 0d7f32817456a0f3937fcfd934afeb32154ca33580ab264dab6c285e6dbbd215 F ext/wasm/jaccwabyt/jaccwabyt.md 447cc02b598f7792edaa8ae6853a7847b8178a18ed356afacbdbf312b2588106 F ext/wasm/jaccwabyt/jaccwabyt_test.c 39e4b865a33548f943e2eb9dd0dc8d619a80de05d5300668e9960fff30d0d36f F ext/wasm/jaccwabyt/jaccwabyt_test.exports 5ff001ef975c426ffe88d7d8a6e96ec725e568d2c2307c416902059339c06f19 -F ext/wasm/kvvfs.make 99d61a438232d03f7a39fff05a5738d00d5af629e54b3f03caf87f041c194d51 +F ext/wasm/kvvfs.make 6f19ef9bdf0394e752b62717db968268206c5237a87541efb825d58945694ff0 F ext/wasm/kvvfs1.html 13bb24190bfb276a57b228499519badcc1bf39ed07e4b37bc2a425ce6418fed1 F ext/wasm/kvvfs1.js ec1c1d071bb055711f9151df05616111432cf3e6bf7ac7f8dcbcfb56c9d9ed48 F ext/wasm/scratchpad-opfs-worker.html 5fdda167571264300f388847d34f00b77dd48984a8dba2ee9c099c3ffa05db66 -F ext/wasm/scratchpad-opfs-worker.js 3ec2868c669713145c76eb5877c64a1b20741f741817b87c907a154b676283a9 -F ext/wasm/scratchpad-opfs-worker2.js 8cd4961e1c96fbaad9743a34cd17d0d27b9286b845e77242d444a4c78fe2a810 +F ext/wasm/scratchpad-opfs-worker.js cf6c4554d3b099c1a50013e50d19b3dc60e183511b4b4dbe7fabc2b9d3360567 +F ext/wasm/scratchpad-opfs-worker2.js 2424d7d7b8801fc143f6540fbdd8a96f3f2e5b811f0f545714d06147ccce58bf F ext/wasm/scratchpad-wasmfs-main.html 20cf6f1a8f368e70d01e8c17200e3eaa90f1c8e1029186d836d14b83845fbe06 F ext/wasm/scratchpad-wasmfs-main.js 69e960e9161f6412fd0c30f355d4112f1894d6609eb431e2d16d207d1380518e F ext/wasm/speedtest1-kvvfs.html fe7d314343b275f8b241af83267ca56274ea995535c6abca4d6e568a98fa31e3 -F ext/wasm/speedtest1-worker.html 6b5fda04d0b69e8c2651689356cb0c28fd33aa1a82b03dcbc8b0d68fbd7ed57f -F ext/wasm/speedtest1-worker.js 356b9953add4449acf199793db9b76b11ee016021918d8daffd19f08ec68d305 -F ext/wasm/speedtest1.html 8f61cbe68300acca25dd9fa74dce79b774786e2b4feeb9bcbc46e1cefbfa6262 +F ext/wasm/speedtest1-wasmfs.html 6a67a6812f03a2058eb5c6ad0c8dea4bf749d0160ed9d6b826dabe7b766c3cf7 +F ext/wasm/speedtest1-worker.html a1dc7611026adad43ddb138172996e13a96dd2d37dcdcb7cef39a130f6b1f57b +F ext/wasm/speedtest1-worker.js fb5d282c0b8aed18daf41c57f768cbf434f8137dbff707d53dcedcd7d4cb60ef +F ext/wasm/speedtest1.html fbb8e4d1639028443f3687a683be660beca6927920545cf6b1fdf503104591c0 F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0 F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5 @@ -529,7 +530,7 @@ F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d766 F ext/wasm/testing1.js 7cd8ab255c238b030d928755ae8e91e7d90a12f2ae601b1b8f7827aaa4fb258e F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3 F ext/wasm/testing2.js 25584bcc30f19673ce13a6f301f89f8820a59dfe044e0c4f2913941f4097fe3c -F ext/wasm/wasmfs.make 44c35734f531199dab7c49f82ed265344c86aa03d741fd7911ddb4de0c551ddd +F ext/wasm/wasmfs.make 21a5cf297954a689e0dc2a95299ae158f681cae5e90c10b99d986097815fd42d F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -2025,8 +2026,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 08476f3c218d45846e7496bdae0b06e2122466111fdf2aa2aabb1805b15ef982 -R 520f42f1cc70efba1aa8d99f68fa03bf +P 4cbbd370186f84e440f496e7f11c641d7dc1723acc46e4a31483392e0eb046e9 +R c453132da1df672225f03816e5e29221 U stephan -Z a50915abdf47f7036b78a2ce4e5a53d8 +Z e87dced3d077599bf1560627688e6f4f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d3cb0d93c3..7d6cc0aac1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4cbbd370186f84e440f496e7f11c641d7dc1723acc46e4a31483392e0eb046e9 \ No newline at end of file +00ee49a3a2c148480f614e49a0ee5b35a255758c0a53693f0b464b31e7a4045b \ No newline at end of file