aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2022-09-29 22:08:22 +0000
committerstephan <stephan@noemail.net>2022-09-29 22:08:22 +0000
commitf71c954cbc07fa0fc8a59e2a8a5a2a32b8e5d95c (patch)
tree44ceac4d12ee7e382ed6d3c8124fa66996617720 /ext/wasm
parentb0ccf50cbd0430eefaf50f5b6c2485ee8d68d6d4 (diff)
downloadsqlite-f71c954cbc07fa0fc8a59e2a8a5a2a32b8e5d95c.tar.gz
sqlite-f71c954cbc07fa0fc8a59e2a8a5a2a32b8e5d95c.zip
Add JS infrastructure to ostensibly allow us to customize the wasm imports, which will hypothetically allow us to eliminate the dependency on EM_JS(), but the corresponding Emscripten glue-level feature currently breaks fatally with WASMFS builds so it's disabled.
FossilOrigin-Name: 88d9253b0db5494bf1c9b6d24f22524eeec856b89e64a66ffb30d945f0df21d3
Diffstat (limited to 'ext/wasm')
-rw-r--r--ext/wasm/GNUmakefile52
-rw-r--r--ext/wasm/README.md1
-rw-r--r--ext/wasm/api/extern-post-js.js2
-rw-r--r--ext/wasm/api/extern-pre-js.js4
-rw-r--r--ext/wasm/api/pre-js.js40
-rw-r--r--ext/wasm/common/whwasmutil.js2
-rw-r--r--ext/wasm/demo-123.js2
-rw-r--r--ext/wasm/fiddle.make7
-rw-r--r--ext/wasm/wasmfs.make21
9 files changed, 108 insertions, 23 deletions
diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile
index ab687d1e4..94cb17a72 100644
--- a/ext/wasm/GNUmakefile
+++ b/ext/wasm/GNUmakefile
@@ -153,6 +153,10 @@ $(sqlite3-api.js): $(sqlite3-api.jses) $(MAKEFILE)
echo "/* END FILE: $$i */"; \
done > $@
+########################################################################
+# --post-js and --pre-js are emcc flags we use to append/prepend JS to
+# the generated emscripten module file.
+pre-js.js := $(dir.api)/pre-js.js
post-js.js := post-js.js
CLEAN_FILES += $(post-js.js)
post-jses := \
@@ -167,8 +171,28 @@ $(post-js.js): $(post-jses) $(MAKEFILE)
echo "/* END FILE: $$i */"; \
done > $@
extern-post-js.js := $(dir.api)/extern-post-js.js
-sqlite3.js.flags.--post-js := --post-js=$(post-js.js) --extern-post-js=$(extern-post-js.js)
-post-jses.deps := $(post-js.js) $(extern-post-js.js)
+extern-pre-js.js := $(dir.api)/extern-pre-js.js
+pre-post-common.flags := \
+ --post-js=$(post-js.js) \
+ --extern-post-js=$(extern-post-js.js) \
+ --extern-pre-js=$(extern-pre-js.js)
+pre-post-jses.deps := $(post-js.js) \
+ $(extern-post-js.js) $(extern-pre-js.js)
+########################################################################
+# call-make-pre-js creates rules for pre-js-$(1).js. $1 = the base
+# name of the JS file on whose behalf this pre-js is for.
+define call-make-pre-js
+pre-post-$(1).flags ?=
+pre-js-$(1).js: $$(pre-js.js) $$(MAKEFILE)
+ cp $$(pre-js.js) $$@
+ echo "Module[xInstantiateWasm].uri = '$(1).wasm';" >> $$@
+CLEAN_FILES += pre-js-$(1).js
+pre-post-$(1).deps := $$(pre-post-jses.deps) pre-js-$(1).js
+pre-post-$(1).flags += --pre-js=pre-js-$(1).js
+endef
+#$(error $(call call-make-pre-js,sqlite3-wasmfs))
+# /post-js and pre-js
+########################################################################
########################################################################
# emcc flags for .c/.o/.wasm/.js.
@@ -202,7 +226,7 @@ emcc.exportedRuntimeMethods := \
emcc.jsflags += $(emcc.exportedRuntimeMethods)
emcc.jsflags += -sUSE_CLOSURE_COMPILER=0
emcc.jsflags += -sIMPORTED_MEMORY
-emcc.environment := -sENVIRONMENT=web
+emcc.environment := -sENVIRONMENT=web,worker
emcc.jsflags += -sALLOW_MEMORY_GROWTH
# emcc: warning: USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code
# slowly, see https://github.com/WebAssembly/design/issues/1271
@@ -264,7 +288,6 @@ emcc.jsflags += -sWASM_BIGINT=$(emcc_enable_bigint)
# code get confused and cannot load property (namely, the
# sqlite3.worker.js generated in conjunction with -sWASMFS).
sqlite3.js := sqlite3.js
-emcc.jsflags += $(sqlite3.js.flags.--post-js)
sqlite3.wasm := sqlite3.wasm
sqlite3-wasm.o := $(dir.api)/sqlite3-wasm.o
$(sqlite3-wasm.o): emcc.cflags += $(SQLITE_OPT)
@@ -276,19 +299,25 @@ jaccwabyt_test.c := $(dir.jacc)/jaccwabyt_test.c
# want to test the release builds with those apps, so we cannot simply
# elide that file in release builds. That component is critical to the
# VFS bindings so needs to be tested along with the core APIs.
-define WASM_C_COMPILE
+########################################################################
+# call-wasm-c-compile sets up build rules
+# for $1.o. $1 must be the name of a C file (with extension).
+define call-wasm-c-compile
$(1).o := $$(subst .c,.o,$(1))
sqlite3.wasm.obj += $$($(1).o)
$$($(1).o): $$(MAKEFILE) $(1)
$$(emcc.bin) $$(emcc_opt_full) $$(emcc.flags) $$(emcc.cflags) -c $(1) -o $$@
CLEAN_FILES += $$($(1).o)
endef
-$(foreach c,$(sqlite3-wasm.c) $(jaccwabyt_test.c),$(eval $(call WASM_C_COMPILE,$(c))))
+$(foreach c,$(sqlite3-wasm.c) $(jaccwabyt_test.c),$(eval $(call call-wasm-c-compile,$(c))))
+$(eval $(call call-make-pre-js,sqlite3))
$(sqlite3.js): $(MAKEFILE) $(sqlite3.wasm.obj) \
EXPORTED_FUNCTIONS.api \
- $(post-jses.deps)
+ $(pre-post-sqlite3.deps)
@echo "Building $@ ..."
- $(emcc.bin) -o $@ $(emcc_opt_full) $(emcc.flags) $(emcc.jsflags) $(sqlite3.wasm.obj)
+ $(emcc.bin) -o $@ $(emcc_opt_full) $(emcc.flags) \
+ $(emcc.jsflags) $(pre-post-common.flags) $(pre-post-sqlite3.flags) \
+ $(sqlite3.wasm.obj)
chmod -x $(sqlite3.wasm)
$(maybe-wasm-strip) $(sqlite3.wasm)
@ls -la $@ $(sqlite3.wasm)
@@ -342,8 +371,8 @@ speedtest1-common.eflags += -sALLOW_TABLE_GROWTH
speedtest1-common.eflags += -sDYNAMIC_EXECUTION=0
speedtest1-common.eflags += --minify 0
speedtest1-common.eflags += -sEXPORT_NAME=$(sqlite3.js.init-func)
-speedtest1-common.eflags += $(sqlite3.js.flags.--post-js)
speedtest1-common.eflags += -sWASM_BIGINT=$(emcc_enable_bigint)
+speedtest1-common.eflags += $(pre-post-common.flags)
speedtest1.exit-runtime0 := -sEXIT_RUNTIME=0
speedtest1.exit-runtime1 := -sEXIT_RUNTIME=1
# Re -sEXIT_RUNTIME=1 vs 0: if it's 1 and speedtest1 crashes, we get
@@ -377,11 +406,14 @@ $(speedtest1.js): emcc.cflags+=
# the latter (predictably) results in a slightly faster binary, but we're
# close enough to the target speed requirements that the 500ms makes a
# difference.
-$(speedtest1.js): $(MAKEFILE) $(speedtest1.cs) $(post-jses.deps) \
+$(eval $(call call-make-pre-js,speedtest1))
+$(speedtest1.js): $(MAKEFILE) $(speedtest1.cs) \
+ $(pre-post-speedtest1.deps) \
EXPORTED_FUNCTIONS.speedtest1
@echo "Building $@ ..."
$(emcc.bin) \
$(speedtest1.eflags) $(speedtest1-common.eflags) $(speedtest1.cflags) \
+ $(pre-post-speedtest1.flags) \
$(SQLITE_OPT) \
$(speedtest1.exit-runtime0) \
-o $@ $(speedtest1.cs) -lm
diff --git a/ext/wasm/README.md b/ext/wasm/README.md
index f95001359..103295384 100644
--- a/ext/wasm/README.md
+++ b/ext/wasm/README.md
@@ -25,6 +25,7 @@ Those parts only need to be run once, but the SDK can be updated using:
```
$ git pull
+$ ./emsdk install latest
$ ./emsdk activate latest
```
diff --git a/ext/wasm/api/extern-post-js.js b/ext/wasm/api/extern-post-js.js
index acb54c3c9..25d2d1b32 100644
--- a/ext/wasm/api/extern-post-js.js
+++ b/ext/wasm/api/extern-post-js.js
@@ -1,4 +1,4 @@
-/* emscripten-js-addenda.js must be appended to the resulting sqlite3.js
+/* extern-post-js.js must be appended to the resulting sqlite3.js
file. */
(function(){
/**
diff --git a/ext/wasm/api/extern-pre-js.js b/ext/wasm/api/extern-pre-js.js
new file mode 100644
index 000000000..26d066d2e
--- /dev/null
+++ b/ext/wasm/api/extern-pre-js.js
@@ -0,0 +1,4 @@
+/* extern-pre-js.js must be prepended to the resulting sqlite3.js
+ file. This file is currently only used for holding snippets during
+ test and development.
+*/
diff --git a/ext/wasm/api/pre-js.js b/ext/wasm/api/pre-js.js
new file mode 100644
index 000000000..f373fecec
--- /dev/null
+++ b/ext/wasm/api/pre-js.js
@@ -0,0 +1,40 @@
+Module['locateFile'] = function(path, prefix) {
+ return prefix + path;
+};
+
+/**
+ Bug warning: this xInstantiateWasm bit must remain disabled
+ until this bug is resolved or wasmfs won't work:
+
+ https://github.com/emscripten-core/emscripten/issues/17951
+*/
+const xInstantiateWasm = 1
+ ? 'emscripten-bug-17951'
+ : 'instantiateWasm';
+Module[xInstantiateWasm] = function callee(imports,onSuccess){
+ imports.foo = function(){};
+ console.warn("instantiateWasm() uri =",callee.uri, self.location.href);
+ const wfetch = ()=>fetch(callee.uri, {credentials: 'same-origin'});
+ const loadWasm = WebAssembly.instantiateStreaming
+ ? function loadWasmStreaming(){
+ return WebAssembly.instantiateStreaming(wfetch(), imports)
+ .then((arg)=>onSuccess(arg.instance, arg.module));
+ }
+ : function loadWasmOldSchool(){ // Safari < v15
+ return wfetch()
+ .then(response => response.arrayBuffer())
+ .then(bytes => WebAssembly.instantiate(bytes, imports))
+ .then((arg)=>onSuccess(arg.instance, arg.module));
+ };
+ loadWasm();
+ return {};
+};
+/*
+ It is literally impossible to get the name of a Worker's own script,
+ so impossible to derive X.wasm from script name X.js. Thus we need,
+ at build-time, to redifine Module['instantiateWasm'].uri by
+ appending it to a build-specific copy of this file with the name of
+ the wasm file. This is apparently why Emscripten hard-codes the name of
+ the wasm file into their glue scripts.
+*/
+Module[xInstantiateWasm].uri = 'sqlite3.wasm';
diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js
index 662978b20..8b6dbdd83 100644
--- a/ext/wasm/common/whwasmutil.js
+++ b/ext/wasm/common/whwasmutil.js
@@ -1538,7 +1538,7 @@ self.WhWasmUtilInstaller = function(target){
- `onload(loadResult,config)`: optional callback. The first
argument is the result object from
- WebAssembly.instanitate[Streaming](). The 2nd is the config
+ WebAssembly.instantiate[Streaming](). The 2nd is the config
object passed to this function. Described in more detail below.
- `imports`: optional imports object for
diff --git a/ext/wasm/demo-123.js b/ext/wasm/demo-123.js
index 00ea1f5bc..37dc7a7af 100644
--- a/ext/wasm/demo-123.js
+++ b/ext/wasm/demo-123.js
@@ -21,6 +21,7 @@
*/
let logHtml;
if(self.window === self /* UI thread */){
+ console.log("Running demo from main UI thread.");
logHtml = function(cssClass,...args){
const ln = document.createElement('div');
if(cssClass) ln.classList.add(cssClass);
@@ -28,6 +29,7 @@
document.body.append(ln);
};
}else{ /* Worker thread */
+ console.log("Running demo from Worker thread.");
logHtml = function(cssClass,...args){
postMessage({
type:'log',
diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make
index c3892263a..6ccf8e029 100644
--- a/ext/wasm/fiddle.make
+++ b/ext/wasm/fiddle.make
@@ -57,10 +57,13 @@ SOAP.js := sqlite3-opfs-async-proxy.js
$(dir.fiddle)/$(SOAP.js): $(SOAP.js)
cp $< $@
+$(eval $(call call-make-pre-js,fiddle-module))
$(fiddle-module.js): $(MAKEFILE) $(MAKEFILE.fiddle) \
EXPORTED_FUNCTIONS.fiddle EXPORTED_RUNTIME_METHODS.fiddle \
- $(fiddle.cs) $(post-jses.deps) $(dir.fiddle)/$(SOAP.js)
- $(emcc.bin) -o $@ $(fiddle.emcc-flags) $(fiddle.cs)
+ $(fiddle.cs) $(pre-post-fiddle.deps) $(dir.fiddle)/$(SOAP.js)
+ $(emcc.bin) -o $@ $(fiddle.emcc-flags) \
+ $(pre-post-common.flags) $(pre-post-fiddle.flags) \
+ $(fiddle.cs)
$(maybe-wasm-strip) $(fiddle-module.wasm)
gzip < $@ > $@.gz
gzip < $(fiddle-module.wasm) > $(fiddle-module.wasm).gz
diff --git a/ext/wasm/wasmfs.make b/ext/wasm/wasmfs.make
index b93f2ab0c..fa8320e58 100644
--- a/ext/wasm/wasmfs.make
+++ b/ext/wasm/wasmfs.make
@@ -22,7 +22,7 @@ sqlite3-wasmfs.flags =
########################################################################
# emcc flags for .c/.o.
sqlite3-wasmfs.cflags :=
-sqlite3-wasmfs.cflags += -std=c99 -fPIC -g
+sqlite3-wasmfs.cflags += -std=c99 -fPIC
sqlite3-wasmfs.cflags += -pthread
sqlite3-wasmfs.cflags += -I. -I.. -I$(dir.top)
sqlite3-wasmfs.cflags += $(SQLITE_OPT) -DSQLITE_WASM_WASMFS
@@ -57,7 +57,6 @@ sqlite3-wasmfs.jsflags += -sIMPORTED_MEMORY
#sqlite3-wasmfs.jsflags += -sTOTAL_STACK=4194304
sqlite3-wasmfs.jsflags += -sEXPORT_NAME=$(sqlite3.js.init-func)
sqlite3-wasmfs.jsflags += -sGLOBAL_BASE=4096 # HYPOTHETICALLY keep func table indexes from overlapping w/ heap addr.
-sqlite3-wasmfs.jsflags += $(sqlite3.js.flags.--post-js)
#sqlite3-wasmfs.jsflags += -sFILESYSTEM=0 # only for experimentation. sqlite3 needs the FS API
# Perhaps the wasmfs build doesn't?
#sqlite3-wasmfs.jsflags += -sABORTING_MALLOC
@@ -70,20 +69,22 @@ sqlite3-wasmfs.jsflags += -sLLD_REPORT_UNDEFINED
sqlite3-wasmfs.jsflags += -sMEMORY64=0
sqlite3-wasmfs.jsflags += -sINITIAL_MEMORY=128450560
sqlite3-wasmfs.fsflags := -pthread -sWASMFS -sPTHREAD_POOL_SIZE=2 -sENVIRONMENT=web,worker
+# -sPTHREAD_POOL_SIZE values of 2 or higher trigger that bug.
sqlite3-wasmfs.jsflags += $(sqlite3-wasmfs.fsflags)
-speedtest1-common.eflags += -sEXPORTED_FUNCTIONS=@$(dir.wasm)/EXPORTED_FUNCTIONS.speedtest1
#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]
sqlite3-wasmfs.jsflags += -sWASM_BIGINT=$(emcc_enable_bigint)
-
+$(eval $(call call-make-pre-js,sqlite3-wasmfs))
+sqlite3-wasmfs.jsflags += $(pre-post-common.flags) $(pre-post-sqlite3-wasmfs.flags)
$(sqlite3-wasmfs.js): $(sqlite3-wasmfs.wasm.c) $(sqlite3-wasm.c) $(sqlite3-wasmfs.extra.c) \
- EXPORTED_FUNCTIONS.api $(sqlite3-wasm.js) $(MAKEFILE) $(MAKEFILE.wasmfs) \
- $(post-jses.deps)
+ EXPORTED_FUNCTIONS.api $(MAKEFILE) $(MAKEFILE.wasmfs) \
+ $(pre-post-sqlite3-wasmfs.deps)
@echo "Building $@ ..."
$(emcc.bin) -o $@ $(emcc_opt_full) $(emcc.flags) \
- $(sqlite3-wasmfs.cflags) $(sqlite3-wasmfs.jsflags) $(sqlite3-wasmfs.wasm.c) $(sqlite3-wasmfs.extra.c)
+ $(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)
@@ -99,13 +100,15 @@ speedtest1-wasmfs.js := speedtest1-wasmfs.js
speedtest1-wasmfs.wasm := $(subst .js,.wasm,$(speedtest1-wasmfs.js))
speedtest1-wasmfs.eflags := $(sqlite3-wasmfs.fsflags)
speedtest1-wasmfs.eflags += $(SQLITE_OPT) -DSQLITE_WASM_WASMFS
-$(speedtest1-wasmfs.js): $(MAKEFILE) $(MAKEFILE.wasmfs)
-#$(speedtest1-wasmfs.js): $(sqlite3-wasmfs.js)
+$(eval $(call call-make-pre-js,speedtest1-wasmfs))
$(speedtest1-wasmfs.js): $(speedtest1.cs) $(sqlite3-wasmfs.js) \
+ $(MAKEFILE) $(MAKEFILE.wasmfs) \
+ $(pre-post-speedtest1-wasmfs.deps) \
EXPORTED_FUNCTIONS.speedtest1
@echo "Building $@ ..."
$(emcc.bin) \
$(speedtest1-wasmfs.eflags) $(speedtest1-common.eflags) \
+ $(pre-post-speedtest1-wasmfs.flags) \
$(speedtest1.cflags) \
$(sqlite3-wasmfs.cflags) \
-o $@ $(speedtest1.cs) -lm