diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 576b8d320f..bcc23feee7 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -193,7 +193,8 @@ emcc.jsflags += -sSTRICT_JS emcc.jsflags += -sDYNAMIC_EXECUTION=0 emcc.jsflags += -sNO_POLYFILL emcc.jsflags += -sEXPORTED_FUNCTIONS=@$(dir.wasm)/EXPORTED_FUNCTIONS.api -emcc.jsflags += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory # wasmMemory==>for -sIMPORTED_MEMORY +emcc.jsflags += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory + # wasmMemory ==> required by our code for use with -sIMPORTED_MEMORY emcc.jsflags += -sUSE_CLOSURE_COMPILER=0 emcc.jsflags += -sIMPORTED_MEMORY emcc.environment := -sENVIRONMENT=web diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index 4a6b71b8ea..814f17fd93 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -70,5 +70,7 @@ _sqlite3_wasm_db_error _sqlite3_wasm_enum_json _sqlite3_wasm_init_opfs _sqlite3_wasm_vfs_unlink +_sqlite3_wasm__emjs_test +_sqlite3_wasm__kvvfsMakeKey _malloc _free diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 5217cfcde3..2d377f2701 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -650,7 +650,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( ["sqlite3_value_type", "int", "*"], ["sqlite3_vfs_find", "*", "string"], ["sqlite3_vfs_register", "int", "*", "int"], - ["sqlite3_wasm_vfs_unlink", "int", "string"] + ["sqlite3_wasm_vfs_unlink", "int", "string"], + ["sqlite3_wasm__emjs_test", undefined, "int"] ]/*capi.wasm.bindingSignatures*/; if(false && capi.wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){ diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index cea6dffa1f..b0e51d068c 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -483,3 +483,147 @@ int sqlite3_wasm_init_opfs(void){ return SQLITE_NOTFOUND; } #endif /* __EMSCRIPTEN__ && SQLITE_WASM_OPFS */ + +#if defined(__EMSCRIPTEN__) // && defined(SQLITE_OS_KV) +#include "emscripten.h" + +#ifndef KVSTORAGE_KEY_SZ +/* We can remove this once kvvfs and this bit is merged. */ +# define KVSTORAGE_KEY_SZ 32 +static void kvstorageMakeKey( + const char *zClass, + const char *zKeyIn, + char *zKeyOut +){ + sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn); +} +#endif + +/* +** An internal level of indirection for accessing the static +** kvstorageMakeKey() from EM_JS()-generated functions. This must be +** made available for export via Emscripten but is not intended to be +** used from client code. If called with a NULL zClass it is a no-op. +** It returns KVSTORAGE_KEY_SZ, so JS code (which cannot see that +** constant) may call it with NULL arguments to get the size of the +** allocation they'll need for a kvvfs key. +** +** Maintenance reminder: Emscripten will install this in the Module +** init scope and will prefix its name with "_". +*/ +int sqlite3_wasm__kvvfsMakeKey(const char *zClass, + const char *zKeyIn, + char *zKeyOut){ + if(zClass) kvstorageMakeKey(zClass, zKeyIn, zKeyOut); + return KVSTORAGE_KEY_SZ; +} + +#if 0 +/* +** Alternately, we can implement kvstorageMakeKey() in JS in such a +** way that it's visible to kvstorageWrite/Delete/Read() but not the +** rest of the world. This impl is considerably more verbose than +** the C impl because writing directly to memory requires more code in +** JS. +*/ +EM_JS(void, kvstorageMakeKeyJS, + (const char *zClass, const char *zKeyIn, char *zKeyOut),{ + const max = 32; + if(!arguments.length) return max; + let n = 0, i = 0, ch = 0; + // Write key prefix to dest... + if(0){ + const prefix = "kvvfs-"; + for(i in prefix) setValue(zKeyOut+(n++), prefix.charCodeAt(i)); + }else{ + // slightly optimized but less readable... + setValue(zKeyOut + (n++), 107/*'k'*/); + setValue(zKeyOut + (n++), 118/*'v'*/); + setValue(zKeyOut + (n++), 118/*'v'*/); + setValue(zKeyOut + (n++), 102/*'f'*/); + setValue(zKeyOut + (n++), 115/*'s'*/); + setValue(zKeyOut + (n++), 45/*'-'*/); + } + // Write zClass to dest... + for(i = 0; n < max && (ch = getValue(zClass+i)); ++n, ++i){ + setValue(zKeyOut + n, ch); + } + // Write "-" separator to dest... + if(n