diff options
Diffstat (limited to 'ext/wasm')
-rw-r--r-- | ext/wasm/GNUmakefile | 35 | ||||
-rw-r--r-- | ext/wasm/api/sqlite3-wasm.c | 90 | ||||
-rw-r--r-- | ext/wasm/example_extra_init.c | 22 | ||||
-rw-r--r-- | ext/wasm/fiddle.make | 2 |
4 files changed, 102 insertions, 47 deletions
diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 20dab446d..f2d6ae9f0 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -189,6 +189,34 @@ else $(info Development build. Use '$(MAKE) release' for a smaller release build.) endif +######################################################################## +# Adding custom C code via sqlite3_wasm_extra_init.c: +# +# If the canonical build process finds the file +# sqlite3_wasm_extra_init.c in the main wasm build directory, it +# arranges to include that file in the build of sqlite3.wasm and +# defines SQLITE_EXTRA_INIT=sqlite3_wasm_extra_init. +# +# sqlite3_wasm_extra_init() must be a function with this signature: +# +# int sqlite3_wasm_extra_init(const char *) +# +# and the sqlite3 library will call it with an argument of NULL one +# time during sqlite3_initialize(). If it returns non-0, +# initialization of the library will fail. +# +# The filename can be overridden with: +# +# make sqlite3_wasm_extra_init.c=my_custom_stuff.c +# +# See example_extra_init.c for an example implementation. +######################################################################## +sqlite3_wasm_extra_init.c ?= $(wildcard sqlite3_wasm_extra_init.c) +ifneq (,$(sqlite3_wasm_extra_init.c)) + $(info Enabling SQLITE_EXTRA_INIT via $(sqlite3_wasm_extra_init.c).) + SQLITE_OPT += -I. -DSQLITE_WASM_EXTRA_INIT +endif + # bin.version-info = binary to output various sqlite3 version info for # embedding in the JS files and in building the distribution zip file. # It must NOT be in $(dir.tmp) because we need it to survive the @@ -576,6 +604,7 @@ endef # https://github.com/emscripten-core/emscripten/issues/14383 sqlite3.wasm := $(dir.dout)/sqlite3.wasm sqlite3-wasm.c := $(dir.api)/sqlite3-wasm.c +sqlite3-wasm.cs := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c) # sqlite3-wasm.o vs sqlite3-wasm.c: building against the latter # (predictably) results in a slightly faster binary. We're close # enough to the target speed requirements that the 500ms makes a @@ -650,12 +679,12 @@ $$(eval $$(call call-make-pre-post,sqlite3,$(1))) emcc.flags.sqlite3.$(1) := $(6) $$(eval $$(call C-PP.FILTER, $$(sqlite3-api.js.in), $(3), $(5))) $(4): $(3) -$(4): $(3) $$(MAKEFILE) $$(sqlite3-wasm.c) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-sqlite3.deps.$(1)) +$(4): $(3) $$(MAKEFILE) $$(sqlite3-wasm.cs) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-sqlite3.deps.$(1)) @echo "Building $$@ ..." $$(emcc.bin) -o $$@ $$(emcc_opt_full) $$(emcc.flags) \ $$(emcc.jsflags) \ $$(pre-post-sqlite3.flags.$(1)) $$(emcc.flags.sqlite3.$(1)) \ - $$(cflags.common) $$(SQLITE_OPT) $$(sqlite3-wasm.c) + $$(cflags.common) $$(SQLITE_OPT) $$(sqlite3-wasm.cs) @$$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(2)) @if [ bundler-friendly = $(1) ]; then \ echo "Patching $(3) for sqlite3.wasm..."; \ @@ -806,7 +835,7 @@ $(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api) speedtest1.js := $(dir.dout)/speedtest1.js speedtest1.wasm := $(dir.dout)/speedtest1.wasm cflags.speedtest1 := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM -speedtest1.cses := $(speedtest1.c) $(sqlite3-wasm.c) +speedtest1.cses := $(speedtest1.c) $(sqlite3-wasm.cs) $(eval $(call call-make-pre-post,speedtest1,vanilla)) $(speedtest1.js): $(MAKEFILE) $(speedtest1.cses) \ $(pre-post-speedtest1.deps.vanilla) \ diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index e7513509c..bcabe922b 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -163,6 +163,10 @@ # define SQLITE_USE_URI 1 #endif +#ifdef SQLITE_WASM_EXTRA_INIT +# define SQLITE_EXTRA_INIT sqlite3_wasm_extra_init +#endif + #include <assert.h> #include "sqlite3.c" /* yes, .c instead of .h. */ @@ -171,7 +175,7 @@ #endif /* -** SQLITE_WASM_KEEP is functionally identical to EMSCRIPTEN_KEEPALIVE +** SQLITE_WASM_EXPORT is functionally identical to EMSCRIPTEN_KEEPALIVE ** but is not Emscripten-specific. It explicitly marks functions for ** export into the target wasm file without requiring explicit listing ** of those functions in Emscripten's -sEXPORTED_FUNCTIONS=... list @@ -193,7 +197,7 @@ ** this writing we are tied to Emscripten for various reasons ** and cannot test the library with other build environments. */ -#define SQLITE_WASM_KEEP __attribute__((used,visibility("default"))) +#define SQLITE_WASM_EXPORT __attribute__((used,visibility("default"))) // See also: //__attribute__((export_name("theExportedName"), used, visibility("default"))) @@ -210,24 +214,24 @@ ** Another option is to malloc() a chunk of our own and call that our ** "stack". */ -SQLITE_WASM_KEEP void * sqlite3_wasm_stack_end(void){ +SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_end(void){ extern void __heap_base /* see https://stackoverflow.com/questions/10038964 */; return &__heap_base; } -SQLITE_WASM_KEEP void * sqlite3_wasm_stack_begin(void){ +SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_begin(void){ extern void __data_end; return &__data_end; } static void * pWasmStackPtr = 0; -SQLITE_WASM_KEEP void * sqlite3_wasm_stack_ptr(void){ +SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_ptr(void){ if(!pWasmStackPtr) pWasmStackPtr = sqlite3_wasm_stack_end(); return pWasmStackPtr; } -SQLITE_WASM_KEEP void sqlite3_wasm_stack_restore(void * p){ +SQLITE_WASM_EXPORT void sqlite3_wasm_stack_restore(void * p){ pWasmStackPtr = p; } -SQLITE_WASM_KEEP void * sqlite3_wasm_stack_alloc(int n){ +SQLITE_WASM_EXPORT void * sqlite3_wasm_stack_alloc(int n){ if(n<=0) return 0; n = (n + 7) & ~7 /* align to 8-byte boundary */; unsigned char * const p = (unsigned char *)sqlite3_wasm_stack_ptr(); @@ -263,14 +267,14 @@ static struct { /* ** Returns the current pstack position. */ -SQLITE_WASM_KEEP void * sqlite3_wasm_pstack_ptr(void){ +SQLITE_WASM_EXPORT void * sqlite3_wasm_pstack_ptr(void){ return PStack.pPos; } /* ** Sets the pstack position poitner to p. Results are undefined if the ** given value did not come from sqlite3_wasm_pstack_ptr(). */ -SQLITE_WASM_KEEP void sqlite3_wasm_pstack_restore(unsigned char * p){ +SQLITE_WASM_EXPORT void sqlite3_wasm_pstack_restore(unsigned char * p){ assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos); assert(0==(p & 0x7)); if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){ @@ -285,7 +289,7 @@ SQLITE_WASM_KEEP void sqlite3_wasm_pstack_restore(unsigned char * p){ ** JS code from having to do so, and most uses of the pstack will ** call for doing so). */ -SQLITE_WASM_KEEP void * sqlite3_wasm_pstack_alloc(int n){ +SQLITE_WASM_EXPORT void * sqlite3_wasm_pstack_alloc(int n){ if( n<=0 ) return 0; //if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */; n = (n + 7) & ~7 /* align to 8-byte boundary */; @@ -298,7 +302,7 @@ SQLITE_WASM_KEEP void * sqlite3_wasm_pstack_alloc(int n){ ** Return the number of bytes left which can be ** sqlite3_wasm_pstack_alloc()'d. */ -SQLITE_WASM_KEEP int sqlite3_wasm_pstack_remaining(void){ +SQLITE_WASM_EXPORT int sqlite3_wasm_pstack_remaining(void){ assert(PStack.pPos >= PStack.pBegin); assert(PStack.pPos <= PStack.pEnd); return (int)(PStack.pPos - PStack.pBegin); @@ -309,7 +313,7 @@ SQLITE_WASM_KEEP int sqlite3_wasm_pstack_remaining(void){ ** any space which is currently allocated. This value is a ** compile-time constant. */ -SQLITE_WASM_KEEP int sqlite3_wasm_pstack_quota(void){ +SQLITE_WASM_EXPORT int sqlite3_wasm_pstack_quota(void){ return (int)(PStack.pEnd - PStack.pBegin); } @@ -327,7 +331,7 @@ SQLITE_WASM_KEEP int sqlite3_wasm_pstack_quota(void){ ** ** Returns err_code. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){ if( db!=0 ){ if( 0!=zMsg ){ @@ -349,7 +353,7 @@ struct WasmTestStruct { void (*xFunc)(void*); }; typedef struct WasmTestStruct WasmTestStruct; -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT void sqlite3_wasm_test_struct(WasmTestStruct * s){ if(s){ s->v4 *= 2; @@ -377,7 +381,7 @@ void sqlite3_wasm_test_struct(WasmTestStruct * s){ ** buffer is not large enough for the generated JSON and needs to be ** increased. In debug builds that will trigger an assert(). */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT const char * sqlite3_wasm_enum_json(void){ static char aBuffer[1024 * 20] = {0} /* where the JSON goes */; int n = 0, nChildren = 0, nStruct = 0 @@ -1182,7 +1186,7 @@ const char * sqlite3_wasm_enum_json(void){ ** method, SQLITE_MISUSE is returned, else the result of the xDelete() ** call is returned. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_vfs_unlink(sqlite3_vfs *pVfs, const char *zName){ int rc = SQLITE_MISUSE /* ??? */; if( 0==pVfs && 0!=zName ) pVfs = sqlite3_vfs_find(0); @@ -1200,7 +1204,7 @@ int sqlite3_wasm_vfs_unlink(sqlite3_vfs *pVfs, const char *zName){ ** defaulting to "main" if zDbName is 0. Returns 0 if no db with the ** given name is open. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT sqlite3_vfs * sqlite3_wasm_db_vfs(sqlite3 *pDb, const char *zDbName){ sqlite3_vfs * pVfs = 0; sqlite3_file_control(pDb, zDbName ? zDbName : "main", @@ -1223,7 +1227,7 @@ sqlite3_vfs * sqlite3_wasm_db_vfs(sqlite3 *pDb, const char *zDbName){ ** Returns 0 on success, an SQLITE_xxx code on error. Returns ** SQLITE_MISUSE if pDb is NULL. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_db_reset(sqlite3 *pDb){ int rc = SQLITE_MISUSE; if( pDb ){ @@ -1254,7 +1258,7 @@ int sqlite3_wasm_db_reset(sqlite3 *pDb){ ** sqlite3_wasm_db_serialize() is arguably the better way to achieve ** this. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_db_export_chunked( sqlite3* pDb, int (*xCallback)(unsigned const char *zOut, int n) ){ sqlite3_int64 nSize = 0; @@ -1305,7 +1309,7 @@ int sqlite3_wasm_db_export_chunked( sqlite3* pDb, ** If `*pOut` is not NULL, the caller is responsible for passing it to ** sqlite3_free() to free it. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema, unsigned char **pOut, sqlite3_int64 *nOut, unsigned int mFlags ){ @@ -1362,7 +1366,7 @@ int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema, ** portability, so that the API can still work in builds where BigInt ** support is disabled or unavailable. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_vfs_create_file( sqlite3_vfs *pVfs, const char *zFilename, const unsigned char * pData, @@ -1446,7 +1450,7 @@ int sqlite3_wasm_vfs_create_file( sqlite3_vfs *pVfs, ** NUL-terminated pointer to that string. It is up to the caller to ** use sqlite3_wasm_pstack_restore() to free the returned pointer. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT char * sqlite3_wasm_kvvfsMakeKeyOnPstack(const char *zClass, const char *zKeyIn){ assert(sqlite3KvvfsMethods.nKeySize>24); @@ -1465,7 +1469,7 @@ char * sqlite3_wasm_kvvfsMakeKeyOnPstack(const char *zClass, ** Returns the pointer to the singleton object which holds the kvvfs ** I/O methods and associated state. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT sqlite3_kvvfs_methods * sqlite3_wasm_kvvfs_methods(void){ return &sqlite3KvvfsMethods; } @@ -1480,7 +1484,7 @@ sqlite3_kvvfs_methods * sqlite3_wasm_kvvfs_methods(void){ ** sqlite3_vtab_config(), or SQLITE_MISUSE if the 2nd arg is not a ** valid value. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_vtab_config(sqlite3 *pDb, int op, int arg){ switch(op){ case SQLITE_VTAB_DIRECTONLY: @@ -1500,7 +1504,7 @@ int sqlite3_wasm_vtab_config(sqlite3 *pDb, int op, int arg){ ** Wrapper for the variants of sqlite3_db_config() which take ** (int,int*) variadic args. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_db_config_ip(sqlite3 *pDb, int op, int arg1, int* pArg2){ switch(op){ case SQLITE_DBCONFIG_ENABLE_FKEY: @@ -1531,7 +1535,7 @@ int sqlite3_wasm_db_config_ip(sqlite3 *pDb, int op, int arg1, int* pArg2){ ** Wrapper for the variants of sqlite3_db_config() which take ** (void*,int,int) variadic args. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_db_config_pii(sqlite3 *pDb, int op, void * pArg1, int arg2, int arg3){ switch(op){ case SQLITE_DBCONFIG_LOOKASIDE: @@ -1547,7 +1551,7 @@ int sqlite3_wasm_db_config_pii(sqlite3 *pDb, int op, void * pArg1, int arg2, int ** Wrapper for the variants of sqlite3_db_config() which take ** (const char *) variadic args. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_db_config_s(sqlite3 *pDb, int op, const char *zArg){ switch(op){ case SQLITE_DBCONFIG_MAINDBNAME: @@ -1564,7 +1568,7 @@ int sqlite3_wasm_db_config_s(sqlite3 *pDb, int op, const char *zArg){ ** Binding for combinations of sqlite3_config() arguments which take ** a single integer argument. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_config_i(int op, int arg){ return sqlite3_config(op, arg); } @@ -1576,7 +1580,7 @@ int sqlite3_wasm_config_i(int op, int arg){ ** Binding for combinations of sqlite3_config() arguments which take ** two int arguments. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_config_ii(int op, int arg1, int arg2){ return sqlite3_config(op, arg1, arg2); } @@ -1588,7 +1592,7 @@ int sqlite3_wasm_config_ii(int op, int arg1, int arg2){ ** Binding for combinations of sqlite3_config() arguments which take ** a single i64 argument. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_config_j(int op, sqlite3_int64 arg){ return sqlite3_config(op, arg); } @@ -1617,7 +1621,7 @@ int sqlite3_wasm_config_j(int op, sqlite3_int64 arg){ ** Safari-specific quirk covered at ** https://sqlite.org/forum/info/e5b20e1feb37a19a. **/ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT void * sqlite3_wasm_ptr_to_sqlite3_free(void){ return (void*)sqlite3_free; } @@ -1647,7 +1651,7 @@ void * sqlite3_wasm_ptr_to_sqlite3_free(void){ ** the virtual FS fails. In builds compiled without SQLITE_ENABLE_WASMFS ** defined, SQLITE_NOTFOUND is returned without side effects. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ static backend_t pOpfs = 0; if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs"; @@ -1667,7 +1671,7 @@ int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ return pOpfs ? 0 : SQLITE_NOMEM; } #else -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_init_wasmfs(const char *zUnused){ //emscripten_console_warn("WASMFS OPFS is not compiled in."); if(zUnused){/*unused*/} @@ -1677,51 +1681,51 @@ int sqlite3_wasm_init_wasmfs(const char *zUnused){ #if SQLITE_WASM_TESTS -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int sqlite3_wasm_test_intptr(int * p){ return *p = *p * 2; } -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT void * sqlite3_wasm_test_voidptr(void * p){ return p; } -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int64_t sqlite3_wasm_test_int64_max(void){ return (int64_t)0x7fffffffffffffff; } -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int64_t sqlite3_wasm_test_int64_min(void){ return ~sqlite3_wasm_test_int64_max(); } -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int64_t sqlite3_wasm_test_int64_times2(int64_t x){ return x * 2; } -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT void sqlite3_wasm_test_int64_minmax(int64_t * min, int64_t *max){ *max = sqlite3_wasm_test_int64_max(); *min = sqlite3_wasm_test_int64_min(); /*printf("minmax: min=%lld, max=%lld\n", *min, *max);*/ } -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT int64_t sqlite3_wasm_test_int64ptr(int64_t * p){ /*printf("sqlite3_wasm_test_int64ptr( @%lld = 0x%llx )\n", (int64_t)p, *p);*/ return *p = *p * 2; } -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT void sqlite3_wasm_test_stack_overflow(int recurse){ if(recurse) sqlite3_wasm_test_stack_overflow(recurse); } /* For testing the 'string:dealloc' whwasmutil.xWrap() conversion. */ -SQLITE_WASM_KEEP +SQLITE_WASM_EXPORT char * sqlite3_wasm_test_str_hello(int fail){ char * s = fail ? 0 : (char *)sqlite3_malloc(6); if(s){ @@ -1732,4 +1736,4 @@ char * sqlite3_wasm_test_str_hello(int fail){ } #endif /* SQLITE_WASM_TESTS */ -#undef SQLITE_WASM_KEEP +#undef SQLITE_WASM_EXPORT diff --git a/ext/wasm/example_extra_init.c b/ext/wasm/example_extra_init.c new file mode 100644 index 000000000..ca7038631 --- /dev/null +++ b/ext/wasm/example_extra_init.c @@ -0,0 +1,22 @@ +/* +** If the canonical build process finds the file +** sqlite3_wasm_extra_init.c in the main wasm build directory, it +** arranges to include that file in the build of sqlite3.wasm and +** defines SQLITE_EXTRA_INIT=sqlite3_wasm_extra_init. +** +** sqlite3_wasm_extra_init() must be a function with this signature: +** +** int sqlite3_wasm_extra_init(const char *) +** +** and the sqlite3 library will call it with an argument of NULL one +** time during sqlite3_initialize(). If it returns non-0, +** initialization of the library will fail. +*/ + +#include "sqlite3.h" +#include <stdio.h> + +int sqlite3_wasm_extra_init(const char *z){ + fprintf(stderr,"%s: %s()\n", __FILE__, __func__); + return 0; +} diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index cbe6ab351..86984c966 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -52,7 +52,7 @@ $(EXPORTED_FUNCTIONS.fiddle): $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE.fiddle) fiddle-module.js := $(dir.fiddle)/fiddle-module.js fiddle-module.wasm := $(subst .js,.wasm,$(fiddle-module.js)) -fiddle.cses := $(dir.top)/shell.c $(sqlite3-wasm.c) +fiddle.cses := $(dir.top)/shell.c $(sqlite3-wasm.cs) fiddle.SOAP.js := $(dir.fiddle)/$(notdir $(SOAP.js)) $(fiddle.SOAP.js): $(SOAP.js) |