xref: /sqlite-3.40.0/ext/wasm/api/pre-js.js (revision 1fc6ffcc)
195639269Sstephan/**
295639269Sstephan   BEGIN FILE: api/pre-js.js
395639269Sstephan
495639269Sstephan   This file is intended to be prepended to the sqlite3.js build using
595639269Sstephan   Emscripten's --pre-js=THIS_FILE flag (or equivalent).
695639269Sstephan*/
7cd0df83cSstephan
8cd0df83cSstephan// See notes in extern-post-js.js
9cd0df83cSstephanconst sqlite3InitModuleState = self.sqlite3InitModuleState || Object.create(null);
10cd0df83cSstephandelete self.sqlite3InitModuleState;
11*1fc6ffccSstephansqlite3InitModuleState.debugModule('self.location =',self.location);
12cd0df83cSstephan
13cd0df83cSstephan/**
14cd0df83cSstephan   This custom locateFile() tries to figure out where to load `path`
15cd0df83cSstephan   from. The intent is to provide a way for foo/bar/X.js loaded from a
16cd0df83cSstephan   Worker constructor or importScripts() to be able to resolve
17cd0df83cSstephan   foo/bar/X.wasm (in the latter case, with some help):
18cd0df83cSstephan
19cd0df83cSstephan   1) If URL param named the same as `path` is set, it is returned.
20cd0df83cSstephan
21cd0df83cSstephan   2) If sqlite3InitModuleState.sqlite3Dir is set, then (thatName + path)
22cd0df83cSstephan      is returned (note that it's assumed to end with '/').
23cd0df83cSstephan
24cd0df83cSstephan   3) If this code is running in the main UI thread AND it was loaded
25cd0df83cSstephan      from a SCRIPT tag, the directory part of that URL is used
26cd0df83cSstephan      as the prefix. (This form of resolution unfortunately does not
27cd0df83cSstephan      function for scripts loaded via importScripts().)
28cd0df83cSstephan
29cd0df83cSstephan   4) If none of the above apply, (prefix+path) is returned.
30cd0df83cSstephan*/
31f71c954cSstephanModule['locateFile'] = function(path, prefix) {
32cd0df83cSstephan  let theFile;
33cd0df83cSstephan  const up = this.urlParams;
34cd0df83cSstephan  if(up.has(path)){
35cd0df83cSstephan    theFile = up.get(path);
36cd0df83cSstephan  }else if(this.sqlite3Dir){
37cd0df83cSstephan    theFile = this.sqlite3Dir + path;
38cd0df83cSstephan  }else if(this.scriptDir){
39cd0df83cSstephan    theFile = this.scriptDir + path;
40cd0df83cSstephan  }else{
41cd0df83cSstephan    theFile = prefix + path;
42cd0df83cSstephan  }
43*1fc6ffccSstephan  sqlite3InitModuleState.debugModule(
44*1fc6ffccSstephan    "locateFile(",arguments[0], ',', arguments[1],")",
45*1fc6ffccSstephan    'sqlite3InitModuleState.scriptDir =',this.scriptDir,
46*1fc6ffccSstephan    'up.entries() =',Array.from(up.entries()),
47*1fc6ffccSstephan    "result =", theFile
48*1fc6ffccSstephan  );
49cd0df83cSstephan  return theFile;
50cd0df83cSstephan}.bind(sqlite3InitModuleState);
51f71c954cSstephan
52f71c954cSstephan/**
53*1fc6ffccSstephan   Bug warning: a custom Module.instantiateWasm() does not work
54*1fc6ffccSstephan   in WASMFS builds:
55f71c954cSstephan
56f71c954cSstephan   https://github.com/emscripten-core/emscripten/issues/17951
57*1fc6ffccSstephan
58*1fc6ffccSstephan   In such builds we must disable this.
59f71c954cSstephan*/
60*1fc6ffccSstephanconst xNameOfInstantiateWasm = true
61*1fc6ffccSstephan      ? 'instantiateWasm'
62*1fc6ffccSstephan      : 'emscripten-bug-17951';
63*1fc6ffccSstephanModule[xNameOfInstantiateWasm] = function callee(imports,onSuccess){
64f6c686c9Sstephan  imports.env.foo = function(){};
65*1fc6ffccSstephan  const uri = Module.locateFile(
66*1fc6ffccSstephan    callee.uri, (
67*1fc6ffccSstephan      ('undefined'===typeof scriptDirectory/*var defined by Emscripten glue*/)
68*1fc6ffccSstephan        ? '' : scriptDirectory)
69*1fc6ffccSstephan  );
70*1fc6ffccSstephan  sqlite3InitModuleState.debugModule(
71*1fc6ffccSstephan    "instantiateWasm() uri =", uri
72*1fc6ffccSstephan  );
73*1fc6ffccSstephan  const wfetch = ()=>fetch(uri, {credentials: 'same-origin'});
74f71c954cSstephan  const loadWasm = WebAssembly.instantiateStreaming
75f6c686c9Sstephan        ? async ()=>{
76f71c954cSstephan          return WebAssembly.instantiateStreaming(wfetch(), imports)
77f71c954cSstephan            .then((arg)=>onSuccess(arg.instance, arg.module));
78f71c954cSstephan        }
79f6c686c9Sstephan        : async ()=>{ // Safari < v15
80f71c954cSstephan          return wfetch()
81f71c954cSstephan            .then(response => response.arrayBuffer())
82f71c954cSstephan            .then(bytes => WebAssembly.instantiate(bytes, imports))
83f71c954cSstephan            .then((arg)=>onSuccess(arg.instance, arg.module));
84f71c954cSstephan        };
85f71c954cSstephan  loadWasm();
86f71c954cSstephan  return {};
87f71c954cSstephan};
88f71c954cSstephan/*
89f6c686c9Sstephan  It is literally impossible to reliably get the name of _this_ script
90f6c686c9Sstephan  at runtime, so impossible to derive X.wasm from script name
91f6c686c9Sstephan  X.js. Thus we need, at build-time, to redefine
92*1fc6ffccSstephan  Module[xNameOfInstantiateWasm].uri by appending it to a build-specific
93f6c686c9Sstephan  copy of this file with the name of the wasm file. This is apparently
94f6c686c9Sstephan  why Emscripten hard-codes the name of the wasm file into their glue
95f6c686c9Sstephan  scripts.
96f71c954cSstephan*/
97*1fc6ffccSstephanModule[xNameOfInstantiateWasm].uri = 'sqlite3.wasm';
98*1fc6ffccSstephan/* END FILE: api/pre-js.js, noting that the build process may add a
99*1fc6ffccSstephan   line after this one to change the above .uri to a build-specific
100*1fc6ffccSstephan   one. */
101