xref: /sqlite-3.40.0/ext/wasm/api/sqlite3-wasm.c (revision 4fbf90ee)
1 /*
2 ** This file requires access to sqlite3.c static state in order to
3 ** implement certain WASM-specific features, and thus directly
4 ** includes that file. Unlike the rest of sqlite3.c, this file
5 ** requires compiling with -std=c99 (or equivalent, or a later C
6 ** version) because it makes use of features not available in C89.
7 **
8 ** At it's simplest, to build sqlite3.wasm either place this file
9 ** in the same directory as sqlite3.c/h before compilation or use the
10 ** -I/path flag to tell the compiler where to find both of those
11 ** files, then compile this file. For example:
12 **
13 ** emcc -o sqlite3.wasm ... -I/path/to/sqlite3-c-and-h sqlite3-wasm.c
14 */
15 
16 #define SQLITE_WASM
17 
18 /*
19 ** Threading and file locking: JS is single-threaded. Each Worker
20 ** thread is a separate instance of the JS engine so can never access
21 ** the same db handle as another thread, thus multi-threading support
22 ** is unnecessary in the library. Because the filesystems are virtual
23 ** and local to a given wasm runtime instance, two Workers can never
24 ** access the same db file at once, with the exception of OPFS. As of
25 ** this writing (2022-09-30), OPFS exclusively locks a file when
26 ** opening it, so two Workers can never open the same OPFS-backed file
27 ** at once. That situation will change if and when lower-level locking
28 ** features are added to OPFS (as is currently planned, per folks
29 ** involved with its development).
30 **
31 ** Summary: except for the case of future OPFS, which supports
32 ** locking, and any similar future filesystems, threading and file
33 ** locking support are unnecessary in the wasm build.
34 */
35 #undef SQLITE_OMIT_DESERIALIZE
36 #ifndef SQLITE_DEFAULT_UNIX_VFS
37 # define SQLITE_DEFAULT_UNIX_VFS "unix-none"
38 #endif
39 #ifndef SQLITE_OMIT_DEPRECATED
40 # define SQLITE_OMIT_DEPRECATED
41 #endif
42 #ifndef SQLITE_OMIT_LOAD_EXTENSION
43 # define SQLITE_OMIT_LOAD_EXTENSION
44 #endif
45 #ifndef SQLITE_OMIT_SHARED_CACHE
46 # define SQLITE_OMIT_SHARED_CACHE
47 #endif
48 #ifndef SQLITE_OMIT_UTF16
49 # define SQLITE_OMIT_UTF16
50 #endif
51 #ifndef SQLITE_OS_KV_OPTIONAL
52 # define SQLITE_OS_KV_OPTIONAL 1
53 #endif
54 #ifndef SQLITE_TEMP_STORE
55 # define SQLITE_TEMP_STORE 3
56 #endif
57 #ifndef SQLITE_THREADSAFE
58 # define SQLITE_THREADSAFE 0
59 #endif
60 #ifndef SQLITE_OMIT_WAL
61 # define SQLITE_OMIT_WAL
62 #endif
63 #ifndef SQLITE_DEFAULT_CACHE_SIZE
64 /*
65 ** The OPFS impls benefit tremendously from an increased cache size
66 ** when working on large workloads, e.g. speedtest1 --size 50 or
67 ** higher. On smaller workloads, e.g. speedtest1 --size 25, they
68 ** clearly benefit from having 4mb of cache, but not as much as a
69 ** larger cache benefits the larger workloads. Speed differences
70 ** between 2x and nearly 3x have been measured with ample page cache.
71 */
72 # define SQLITE_DEFAULT_CACHE_SIZE -16777216
73 #endif
74 
75 #if 0
76 /*
77 ** TODO: experiment with this when back on the opfs-capable machine.
78 */
79 #ifndef SQLITE_DEFAULT_PAGE_SIZE
80 # define SQLITE_DEFAULT_PAGE_SIZE 8192 /*4096*/
81 #endif
82 #endif
83 
84 #include <assert.h>
85 #include "sqlite3.c" /* yes, .c instead of .h. */
86 
87 #if defined(__EMSCRIPTEN__)
88 #  include <emscripten/console.h>
89 #endif
90 
91 /*
92 ** SQLITE_WASM_KEEP is identical to EMSCRIPTEN_KEEPALIVE but is not
93 ** Emscripten-specific. It explicitly marks functions for export into
94 ** the target wasm file without requiring explicit listing of those
95 ** functions in Emscripten's -sEXPORTED_FUNCTIONS=... list (or
96 ** equivalent in other build platforms). Any function with neither
97 ** this attribute nor which is listed as an explicit export will not
98 ** be exported from the wasm file (but may still be used internally
99 ** within the wasm file).
100 **
101 ** The functions in this file (sqlite3-wasm.c) which require exporting
102 ** are marked with this flag. They may also be added to any explicit
103 ** build-time export list but need not be. All of these APIs are
104 ** intended for use only within the project's own JS/WASM code, and
105 ** not by client code, so an argument can be made for reducing their
106 ** visibility by not including them in any build-time export lists.
107 **
108 ** 2022-09-11: it's not yet _proven_ that this approach works in
109 ** non-Emscripten builds. If not, such builds will need to export
110 ** those using the --export=... wasm-ld flag (or equivalent). As of
111 ** this writing we are tied to Emscripten for various reasons
112 ** and cannot test the library with other build environments.
113 */
114 #define WASM_KEEP __attribute__((used,visibility("default")))
115 // See also:
116 //__attribute__((export_name("theExportedName"), used, visibility("default")))
117 
118 
119 #if 0
120 /*
121 ** An EXPERIMENT in implementing a stack-based allocator analog to
122 ** Emscripten's stackSave(), stackAlloc(), stackRestore().
123 ** Unfortunately, this cannot work together with Emscripten because
124 ** Emscripten defines its own native one and we'd stomp on each
125 ** other's memory. Other than that complication, basic tests show it
126 ** to work just fine.
127 **
128 ** Another option is to malloc() a chunk of our own and call that our
129 ** "stack".
130 */
131 WASM_KEEP void * sqlite3_wasm_stack_end(void){
132   extern void __heap_base
133     /* see https://stackoverflow.com/questions/10038964 */;
134   return &__heap_base;
135 }
136 WASM_KEEP void * sqlite3_wasm_stack_begin(void){
137   extern void __data_end;
138   return &__data_end;
139 }
140 static void * pWasmStackPtr = 0;
141 WASM_KEEP void * sqlite3_wasm_stack_ptr(void){
142   if(!pWasmStackPtr) pWasmStackPtr = sqlite3_wasm_stack_end();
143   return pWasmStackPtr;
144 }
145 WASM_KEEP void sqlite3_wasm_stack_restore(void * p){
146   pWasmStackPtr = p;
147 }
148 WASM_KEEP void * sqlite3_wasm_stack_alloc(int n){
149   if(n<=0) return 0;
150   n = (n + 7) & ~7 /* align to 8-byte boundary */;
151   unsigned char * const p = (unsigned char *)sqlite3_wasm_stack_ptr();
152   unsigned const char * const b = (unsigned const char *)sqlite3_wasm_stack_begin();
153   if(b + n >= p || b + n < b/*overflow*/) return 0;
154   return pWasmStackPtr = p - n;
155 }
156 #endif /* stack allocator experiment */
157 
158 /*
159 ** State for the "pseudo-stack" allocator implemented in
160 ** sqlite3_wasm_pstack_xyz(). In order to avoid colliding with
161 ** Emscripten-controled stack space, it carves out a bit of stack
162 ** memory to use for that purpose. This memory ends up in the
163 ** WASM-managed memory, such that routines which manipulate the wasm
164 ** heap can also be used to manipulate this memory.
165 **
166 ** This particular allocator is intended for small allocations such as
167 ** storage for output pointers. We cannot reasonably size it large
168 ** enough for general-purpose string conversions because some of our
169 ** tests use input files (strings) of 16MB+.
170 */
171 static unsigned char PStack_mem[512 * 8] = {0};
172 static struct {
173   unsigned const char * const pBegin;/* Start (inclusive) of memory */
174   unsigned const char * const pEnd;  /* One-after-the-end of memory */
175   unsigned char * pPos;              /* Current stack pointer */
176 } PStack = {
177   &PStack_mem[0],
178   &PStack_mem[0] + sizeof(PStack_mem),
179   &PStack_mem[0] + sizeof(PStack_mem)
180 };
181 /*
182 ** Returns the current pstack position.
183 */
184 WASM_KEEP void * sqlite3_wasm_pstack_ptr(void){
185   return PStack.pPos;
186 }
187 /*
188 ** Sets the pstack position poitner to p. Results are undefined if the
189 ** given value did not come from sqlite3_wasm_pstack_ptr().
190 */
191 WASM_KEEP void sqlite3_wasm_pstack_restore(unsigned char * p){
192   assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos);
193   assert(0==(p & 0x7));
194   if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){
195     PStack.pPos = p;
196   }
197 }
198 /*
199 ** Allocate and zero out n bytes from the pstack. Returns a pointer to
200 ** the memory on success, 0 on error (including a negative n value). n
201 ** is always adjusted to be a multiple of 8 and returned memory is
202 ** always zeroed out before returning (because this keeps the client
203 ** JS code from having to do so, and most uses of the pstack will
204 ** call for doing so).
205 */
206 WASM_KEEP void * sqlite3_wasm_pstack_alloc(int n){
207   if( n<=0 ) return 0;
208   //if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */;
209   n = (n + 7) & ~7 /* align to 8-byte boundary */;
210   if( PStack.pBegin + n > PStack.pPos /*not enough space left*/
211       || PStack.pBegin + n <= PStack.pBegin /*overflow*/ ) return 0;
212   memset((PStack.pPos = PStack.pPos - n), 0, (unsigned int)n);
213   return PStack.pPos;
214 }
215 /*
216 ** Return the number of bytes left which can be
217 ** sqlite3_wasm_pstack_alloc()'d.
218 */
219 WASM_KEEP int sqlite3_wasm_pstack_remaining(void){
220   assert(PStack.pPos >= PStack.pBegin);
221   assert(PStack.pPos <= PStack.pEnd);
222   return (int)(PStack.pPos - PStack.pBegin);
223 }
224 
225 /*
226 ** Return the total number of bytes available in the pstack, including
227 ** any space which is currently allocated. This value is a
228 ** compile-time constant.
229 */
230 WASM_KEEP int sqlite3_wasm_pstack_quota(void){
231   return (int)(PStack.pEnd - PStack.pBegin);
232 }
233 
234 /*
235 ** This function is NOT part of the sqlite3 public API. It is strictly
236 ** for use by the sqlite project's own JS/WASM bindings.
237 **
238 ** For purposes of certain hand-crafted C/Wasm function bindings, we
239 ** need a way of reporting errors which is consistent with the rest of
240 ** the C API, as opposed to throwing JS exceptions. To that end, this
241 ** internal-use-only function is a thin proxy around
242 ** sqlite3ErrorWithMessage(). The intent is that it only be used from
243 ** Wasm bindings such as sqlite3_prepare_v2/v3(), and definitely not
244 ** from client code.
245 **
246 ** Returns err_code.
247 */
248 WASM_KEEP
249 int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){
250   if(0!=zMsg){
251     const int nMsg = sqlite3Strlen30(zMsg);
252     sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg);
253   }else{
254     sqlite3ErrorWithMsg(db, err_code, NULL);
255   }
256   return err_code;
257 }
258 
259 /*
260 ** This function is NOT part of the sqlite3 public API. It is strictly
261 ** for use by the sqlite project's own JS/WASM bindings. Unlike the
262 ** rest of the sqlite3 API, this part requires C99 for snprintf() and
263 ** variadic macros.
264 **
265 ** Returns a string containing a JSON-format "enum" of C-level
266 ** constants and struct-related metadata intended to be imported into
267 ** the JS environment. The JSON is initialized the first time this
268 ** function is called and that result is reused for all future calls.
269 **
270 ** If this function returns NULL then it means that the internal
271 ** buffer is not large enough for the generated JSON and needs to be
272 ** increased. In debug builds that will trigger an assert().
273 */
274 WASM_KEEP
275 const char * sqlite3_wasm_enum_json(void){
276   static char aBuffer[1024 * 12] = {0} /* where the JSON goes */;
277   int n = 0, nChildren = 0, nStruct = 0
278     /* output counters for figuring out where commas go */;
279   char * zPos = &aBuffer[1] /* skip first byte for now to help protect
280                           ** against a small race condition */;
281   char const * const zEnd = &aBuffer[0] + sizeof(aBuffer) /* one-past-the-end */;
282   if(aBuffer[0]) return aBuffer;
283   /* Leave aBuffer[0] at 0 until the end to help guard against a tiny
284   ** race condition. If this is called twice concurrently, they might
285   ** end up both writing to aBuffer, but they'll both write the same
286   ** thing, so that's okay. If we set byte 0 up front then the 2nd
287   ** instance might return and use the string before the 1st instance
288   ** is done filling it. */
289 
290 /* Core output macros... */
291 #define lenCheck assert(zPos < zEnd - 128 \
292   && "sqlite3_wasm_enum_json() buffer is too small."); \
293   if( zPos >= zEnd - 128 ) return 0
294 #define outf(format,...) \
295   zPos += snprintf(zPos, ((size_t)(zEnd - zPos)), format, __VA_ARGS__); \
296   lenCheck
297 #define out(TXT) outf("%s",TXT)
298 #define CloseBrace(LEVEL) \
299   assert(LEVEL<5); memset(zPos, '}', LEVEL); zPos+=LEVEL; lenCheck
300 
301 /* Macros for emitting maps of integer- and string-type macros to
302 ** their values. */
303 #define DefGroup(KEY) n = 0; \
304   outf("%s\"" #KEY "\": {",(nChildren++ ? "," : ""));
305 #define DefInt(KEY)                                     \
306   outf("%s\"%s\": %d", (n++ ? ", " : ""), #KEY, (int)KEY)
307 #define DefStr(KEY)                                     \
308   outf("%s\"%s\": \"%s\"", (n++ ? ", " : ""), #KEY, KEY)
309 #define _DefGroup CloseBrace(1)
310 
311   /* The following groups are sorted alphabetic by group name. */
312   DefGroup(access){
313     DefInt(SQLITE_ACCESS_EXISTS);
314     DefInt(SQLITE_ACCESS_READWRITE);
315     DefInt(SQLITE_ACCESS_READ)/*docs say this is unused*/;
316   } _DefGroup;
317 
318   DefGroup(blobFinalizers) {
319     /* SQLITE_STATIC/TRANSIENT need to be handled explicitly as
320     ** integers to avoid casting-related warnings. */
321     out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1");
322   } _DefGroup;
323 
324   DefGroup(dataTypes) {
325     DefInt(SQLITE_INTEGER);
326     DefInt(SQLITE_FLOAT);
327     DefInt(SQLITE_TEXT);
328     DefInt(SQLITE_BLOB);
329     DefInt(SQLITE_NULL);
330   } _DefGroup;
331 
332   DefGroup(encodings) {
333     /* Noting that the wasm binding only aims to support UTF-8. */
334     DefInt(SQLITE_UTF8);
335     DefInt(SQLITE_UTF16LE);
336     DefInt(SQLITE_UTF16BE);
337     DefInt(SQLITE_UTF16);
338     /*deprecated DefInt(SQLITE_ANY); */
339     DefInt(SQLITE_UTF16_ALIGNED);
340   } _DefGroup;
341 
342   DefGroup(fcntl) {
343     DefInt(SQLITE_FCNTL_LOCKSTATE);
344     DefInt(SQLITE_FCNTL_GET_LOCKPROXYFILE);
345     DefInt(SQLITE_FCNTL_SET_LOCKPROXYFILE);
346     DefInt(SQLITE_FCNTL_LAST_ERRNO);
347     DefInt(SQLITE_FCNTL_SIZE_HINT);
348     DefInt(SQLITE_FCNTL_CHUNK_SIZE);
349     DefInt(SQLITE_FCNTL_FILE_POINTER);
350     DefInt(SQLITE_FCNTL_SYNC_OMITTED);
351     DefInt(SQLITE_FCNTL_WIN32_AV_RETRY);
352     DefInt(SQLITE_FCNTL_PERSIST_WAL);
353     DefInt(SQLITE_FCNTL_OVERWRITE);
354     DefInt(SQLITE_FCNTL_VFSNAME);
355     DefInt(SQLITE_FCNTL_POWERSAFE_OVERWRITE);
356     DefInt(SQLITE_FCNTL_PRAGMA);
357     DefInt(SQLITE_FCNTL_BUSYHANDLER);
358     DefInt(SQLITE_FCNTL_TEMPFILENAME);
359     DefInt(SQLITE_FCNTL_MMAP_SIZE);
360     DefInt(SQLITE_FCNTL_TRACE);
361     DefInt(SQLITE_FCNTL_HAS_MOVED);
362     DefInt(SQLITE_FCNTL_SYNC);
363     DefInt(SQLITE_FCNTL_COMMIT_PHASETWO);
364     DefInt(SQLITE_FCNTL_WIN32_SET_HANDLE);
365     DefInt(SQLITE_FCNTL_WAL_BLOCK);
366     DefInt(SQLITE_FCNTL_ZIPVFS);
367     DefInt(SQLITE_FCNTL_RBU);
368     DefInt(SQLITE_FCNTL_VFS_POINTER);
369     DefInt(SQLITE_FCNTL_JOURNAL_POINTER);
370     DefInt(SQLITE_FCNTL_WIN32_GET_HANDLE);
371     DefInt(SQLITE_FCNTL_PDB);
372     DefInt(SQLITE_FCNTL_BEGIN_ATOMIC_WRITE);
373     DefInt(SQLITE_FCNTL_COMMIT_ATOMIC_WRITE);
374     DefInt(SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE);
375     DefInt(SQLITE_FCNTL_LOCK_TIMEOUT);
376     DefInt(SQLITE_FCNTL_DATA_VERSION);
377     DefInt(SQLITE_FCNTL_SIZE_LIMIT);
378     DefInt(SQLITE_FCNTL_CKPT_DONE);
379     DefInt(SQLITE_FCNTL_RESERVE_BYTES);
380     DefInt(SQLITE_FCNTL_CKPT_START);
381     DefInt(SQLITE_FCNTL_EXTERNAL_READER);
382     DefInt(SQLITE_FCNTL_CKSM_FILE);
383   } _DefGroup;
384 
385   DefGroup(flock) {
386     DefInt(SQLITE_LOCK_NONE);
387     DefInt(SQLITE_LOCK_SHARED);
388     DefInt(SQLITE_LOCK_RESERVED);
389     DefInt(SQLITE_LOCK_PENDING);
390     DefInt(SQLITE_LOCK_EXCLUSIVE);
391   } _DefGroup;
392 
393   DefGroup(ioCap) {
394     DefInt(SQLITE_IOCAP_ATOMIC);
395     DefInt(SQLITE_IOCAP_ATOMIC512);
396     DefInt(SQLITE_IOCAP_ATOMIC1K);
397     DefInt(SQLITE_IOCAP_ATOMIC2K);
398     DefInt(SQLITE_IOCAP_ATOMIC4K);
399     DefInt(SQLITE_IOCAP_ATOMIC8K);
400     DefInt(SQLITE_IOCAP_ATOMIC16K);
401     DefInt(SQLITE_IOCAP_ATOMIC32K);
402     DefInt(SQLITE_IOCAP_ATOMIC64K);
403     DefInt(SQLITE_IOCAP_SAFE_APPEND);
404     DefInt(SQLITE_IOCAP_SEQUENTIAL);
405     DefInt(SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN);
406     DefInt(SQLITE_IOCAP_POWERSAFE_OVERWRITE);
407     DefInt(SQLITE_IOCAP_IMMUTABLE);
408     DefInt(SQLITE_IOCAP_BATCH_ATOMIC);
409   } _DefGroup;
410 
411   DefGroup(openFlags) {
412     /* Noting that not all of these will have any effect in
413     ** WASM-space. */
414     DefInt(SQLITE_OPEN_READONLY);
415     DefInt(SQLITE_OPEN_READWRITE);
416     DefInt(SQLITE_OPEN_CREATE);
417     DefInt(SQLITE_OPEN_URI);
418     DefInt(SQLITE_OPEN_MEMORY);
419     DefInt(SQLITE_OPEN_NOMUTEX);
420     DefInt(SQLITE_OPEN_FULLMUTEX);
421     DefInt(SQLITE_OPEN_SHAREDCACHE);
422     DefInt(SQLITE_OPEN_PRIVATECACHE);
423     DefInt(SQLITE_OPEN_EXRESCODE);
424     DefInt(SQLITE_OPEN_NOFOLLOW);
425     /* OPEN flags for use with VFSes... */
426     DefInt(SQLITE_OPEN_MAIN_DB);
427     DefInt(SQLITE_OPEN_MAIN_JOURNAL);
428     DefInt(SQLITE_OPEN_TEMP_DB);
429     DefInt(SQLITE_OPEN_TEMP_JOURNAL);
430     DefInt(SQLITE_OPEN_TRANSIENT_DB);
431     DefInt(SQLITE_OPEN_SUBJOURNAL);
432     DefInt(SQLITE_OPEN_SUPER_JOURNAL);
433     DefInt(SQLITE_OPEN_WAL);
434     DefInt(SQLITE_OPEN_DELETEONCLOSE);
435     DefInt(SQLITE_OPEN_EXCLUSIVE);
436   } _DefGroup;
437 
438   DefGroup(prepareFlags) {
439     DefInt(SQLITE_PREPARE_PERSISTENT);
440     DefInt(SQLITE_PREPARE_NORMALIZE);
441     DefInt(SQLITE_PREPARE_NO_VTAB);
442   } _DefGroup;
443 
444   DefGroup(resultCodes) {
445     DefInt(SQLITE_OK);
446     DefInt(SQLITE_ERROR);
447     DefInt(SQLITE_INTERNAL);
448     DefInt(SQLITE_PERM);
449     DefInt(SQLITE_ABORT);
450     DefInt(SQLITE_BUSY);
451     DefInt(SQLITE_LOCKED);
452     DefInt(SQLITE_NOMEM);
453     DefInt(SQLITE_READONLY);
454     DefInt(SQLITE_INTERRUPT);
455     DefInt(SQLITE_IOERR);
456     DefInt(SQLITE_CORRUPT);
457     DefInt(SQLITE_NOTFOUND);
458     DefInt(SQLITE_FULL);
459     DefInt(SQLITE_CANTOPEN);
460     DefInt(SQLITE_PROTOCOL);
461     DefInt(SQLITE_EMPTY);
462     DefInt(SQLITE_SCHEMA);
463     DefInt(SQLITE_TOOBIG);
464     DefInt(SQLITE_CONSTRAINT);
465     DefInt(SQLITE_MISMATCH);
466     DefInt(SQLITE_MISUSE);
467     DefInt(SQLITE_NOLFS);
468     DefInt(SQLITE_AUTH);
469     DefInt(SQLITE_FORMAT);
470     DefInt(SQLITE_RANGE);
471     DefInt(SQLITE_NOTADB);
472     DefInt(SQLITE_NOTICE);
473     DefInt(SQLITE_WARNING);
474     DefInt(SQLITE_ROW);
475     DefInt(SQLITE_DONE);
476     // Extended Result Codes
477     DefInt(SQLITE_ERROR_MISSING_COLLSEQ);
478     DefInt(SQLITE_ERROR_RETRY);
479     DefInt(SQLITE_ERROR_SNAPSHOT);
480     DefInt(SQLITE_IOERR_READ);
481     DefInt(SQLITE_IOERR_SHORT_READ);
482     DefInt(SQLITE_IOERR_WRITE);
483     DefInt(SQLITE_IOERR_FSYNC);
484     DefInt(SQLITE_IOERR_DIR_FSYNC);
485     DefInt(SQLITE_IOERR_TRUNCATE);
486     DefInt(SQLITE_IOERR_FSTAT);
487     DefInt(SQLITE_IOERR_UNLOCK);
488     DefInt(SQLITE_IOERR_RDLOCK);
489     DefInt(SQLITE_IOERR_DELETE);
490     DefInt(SQLITE_IOERR_BLOCKED);
491     DefInt(SQLITE_IOERR_NOMEM);
492     DefInt(SQLITE_IOERR_ACCESS);
493     DefInt(SQLITE_IOERR_CHECKRESERVEDLOCK);
494     DefInt(SQLITE_IOERR_LOCK);
495     DefInt(SQLITE_IOERR_CLOSE);
496     DefInt(SQLITE_IOERR_DIR_CLOSE);
497     DefInt(SQLITE_IOERR_SHMOPEN);
498     DefInt(SQLITE_IOERR_SHMSIZE);
499     DefInt(SQLITE_IOERR_SHMLOCK);
500     DefInt(SQLITE_IOERR_SHMMAP);
501     DefInt(SQLITE_IOERR_SEEK);
502     DefInt(SQLITE_IOERR_DELETE_NOENT);
503     DefInt(SQLITE_IOERR_MMAP);
504     DefInt(SQLITE_IOERR_GETTEMPPATH);
505     DefInt(SQLITE_IOERR_CONVPATH);
506     DefInt(SQLITE_IOERR_VNODE);
507     DefInt(SQLITE_IOERR_AUTH);
508     DefInt(SQLITE_IOERR_BEGIN_ATOMIC);
509     DefInt(SQLITE_IOERR_COMMIT_ATOMIC);
510     DefInt(SQLITE_IOERR_ROLLBACK_ATOMIC);
511     DefInt(SQLITE_IOERR_DATA);
512     DefInt(SQLITE_IOERR_CORRUPTFS);
513     DefInt(SQLITE_LOCKED_SHAREDCACHE);
514     DefInt(SQLITE_LOCKED_VTAB);
515     DefInt(SQLITE_BUSY_RECOVERY);
516     DefInt(SQLITE_BUSY_SNAPSHOT);
517     DefInt(SQLITE_BUSY_TIMEOUT);
518     DefInt(SQLITE_CANTOPEN_NOTEMPDIR);
519     DefInt(SQLITE_CANTOPEN_ISDIR);
520     DefInt(SQLITE_CANTOPEN_FULLPATH);
521     DefInt(SQLITE_CANTOPEN_CONVPATH);
522     //DefInt(SQLITE_CANTOPEN_DIRTYWAL)/*docs say not used*/;
523     DefInt(SQLITE_CANTOPEN_SYMLINK);
524     DefInt(SQLITE_CORRUPT_VTAB);
525     DefInt(SQLITE_CORRUPT_SEQUENCE);
526     DefInt(SQLITE_CORRUPT_INDEX);
527     DefInt(SQLITE_READONLY_RECOVERY);
528     DefInt(SQLITE_READONLY_CANTLOCK);
529     DefInt(SQLITE_READONLY_ROLLBACK);
530     DefInt(SQLITE_READONLY_DBMOVED);
531     DefInt(SQLITE_READONLY_CANTINIT);
532     DefInt(SQLITE_READONLY_DIRECTORY);
533     DefInt(SQLITE_ABORT_ROLLBACK);
534     DefInt(SQLITE_CONSTRAINT_CHECK);
535     DefInt(SQLITE_CONSTRAINT_COMMITHOOK);
536     DefInt(SQLITE_CONSTRAINT_FOREIGNKEY);
537     DefInt(SQLITE_CONSTRAINT_FUNCTION);
538     DefInt(SQLITE_CONSTRAINT_NOTNULL);
539     DefInt(SQLITE_CONSTRAINT_PRIMARYKEY);
540     DefInt(SQLITE_CONSTRAINT_TRIGGER);
541     DefInt(SQLITE_CONSTRAINT_UNIQUE);
542     DefInt(SQLITE_CONSTRAINT_VTAB);
543     DefInt(SQLITE_CONSTRAINT_ROWID);
544     DefInt(SQLITE_CONSTRAINT_PINNED);
545     DefInt(SQLITE_CONSTRAINT_DATATYPE);
546     DefInt(SQLITE_NOTICE_RECOVER_WAL);
547     DefInt(SQLITE_NOTICE_RECOVER_ROLLBACK);
548     DefInt(SQLITE_WARNING_AUTOINDEX);
549     DefInt(SQLITE_AUTH_USER);
550     DefInt(SQLITE_OK_LOAD_PERMANENTLY);
551     //DefInt(SQLITE_OK_SYMLINK) /* internal use only */;
552   } _DefGroup;
553 
554   DefGroup(serialize){
555     DefInt(SQLITE_SERIALIZE_NOCOPY);
556     DefInt(SQLITE_DESERIALIZE_FREEONCLOSE);
557     DefInt(SQLITE_DESERIALIZE_READONLY);
558     DefInt(SQLITE_DESERIALIZE_RESIZEABLE);
559   } _DefGroup;
560 
561   DefGroup(syncFlags) {
562     DefInt(SQLITE_SYNC_NORMAL);
563     DefInt(SQLITE_SYNC_FULL);
564     DefInt(SQLITE_SYNC_DATAONLY);
565   } _DefGroup;
566 
567   DefGroup(trace) {
568     DefInt(SQLITE_TRACE_STMT);
569     DefInt(SQLITE_TRACE_PROFILE);
570     DefInt(SQLITE_TRACE_ROW);
571     DefInt(SQLITE_TRACE_CLOSE);
572   } _DefGroup;
573 
574   DefGroup(udfFlags) {
575     DefInt(SQLITE_DETERMINISTIC);
576     DefInt(SQLITE_DIRECTONLY);
577     DefInt(SQLITE_INNOCUOUS);
578   } _DefGroup;
579 
580   DefGroup(version) {
581     DefInt(SQLITE_VERSION_NUMBER);
582     DefStr(SQLITE_VERSION);
583     DefStr(SQLITE_SOURCE_ID);
584   } _DefGroup;
585 
586 #undef DefGroup
587 #undef DefStr
588 #undef DefInt
589 #undef _DefGroup
590 
591   /*
592   ** Emit an array of "StructBinder" struct descripions, which look
593   ** like:
594   **
595   ** {
596   **   "name": "MyStruct",
597   **   "sizeof": 16,
598   **   "members": {
599   **     "member1": {"offset": 0,"sizeof": 4,"signature": "i"},
600   **     "member2": {"offset": 4,"sizeof": 4,"signature": "p"},
601   **     "member3": {"offset": 8,"sizeof": 8,"signature": "j"}
602   **   }
603   ** }
604   **
605   ** Detailed documentation for those bits are in the docs for the
606   ** Jaccwabyt JS-side component.
607   */
608 
609   /** Macros for emitting StructBinder description. */
610 #define StructBinder__(TYPE)                 \
611   n = 0;                                     \
612   outf("%s{", (nStruct++ ? ", " : ""));  \
613   out("\"name\": \"" # TYPE "\",");         \
614   outf("\"sizeof\": %d", (int)sizeof(TYPE)); \
615   out(",\"members\": {");
616 #define StructBinder_(T) StructBinder__(T)
617   /** ^^^ indirection needed to expand CurrentStruct */
618 #define StructBinder StructBinder_(CurrentStruct)
619 #define _StructBinder CloseBrace(2)
620 #define M(MEMBER,SIG)                                         \
621   outf("%s\"%s\": "                                           \
622        "{\"offset\":%d,\"sizeof\": %d,\"signature\":\"%s\"}", \
623        (n++ ? ", " : ""), #MEMBER,                            \
624        (int)offsetof(CurrentStruct,MEMBER),                   \
625        (int)sizeof(((CurrentStruct*)0)->MEMBER),              \
626        SIG)
627 
628   nStruct = 0;
629   out(", \"structs\": ["); {
630 
631 #define CurrentStruct sqlite3_vfs
632     StructBinder {
633       M(iVersion,"i");
634       M(szOsFile,"i");
635       M(mxPathname,"i");
636       M(pNext,"p");
637       M(zName,"s");
638       M(pAppData,"p");
639       M(xOpen,"i(pppip)");
640       M(xDelete,"i(ppi)");
641       M(xAccess,"i(ppip)");
642       M(xFullPathname,"i(ppip)");
643       M(xDlOpen,"p(pp)");
644       M(xDlError,"p(pip)");
645       M(xDlSym,"p()");
646       M(xDlClose,"v(pp)");
647       M(xRandomness,"i(pip)");
648       M(xSleep,"i(pi)");
649       M(xCurrentTime,"i(pp)");
650       M(xGetLastError,"i(pip)");
651       M(xCurrentTimeInt64,"i(pp)");
652       M(xSetSystemCall,"i(ppp)");
653       M(xGetSystemCall,"p(pp)");
654       M(xNextSystemCall,"p(pp)");
655     } _StructBinder;
656 #undef CurrentStruct
657 
658 #define CurrentStruct sqlite3_io_methods
659     StructBinder {
660       M(iVersion,"i");
661       M(xClose,"i(p)");
662       M(xRead,"i(ppij)");
663       M(xWrite,"i(ppij)");
664       M(xTruncate,"i(pj)");
665       M(xSync,"i(pi)");
666       M(xFileSize,"i(pp)");
667       M(xLock,"i(pi)");
668       M(xUnlock,"i(pi)");
669       M(xCheckReservedLock,"i(pp)");
670       M(xFileControl,"i(pip)");
671       M(xSectorSize,"i(p)");
672       M(xDeviceCharacteristics,"i(p)");
673       M(xShmMap,"i(piiip)");
674       M(xShmLock,"i(piii)");
675       M(xShmBarrier,"v(p)");
676       M(xShmUnmap,"i(pi)");
677       M(xFetch,"i(pjip)");
678       M(xUnfetch,"i(pjp)");
679     } _StructBinder;
680 #undef CurrentStruct
681 
682 #define CurrentStruct sqlite3_file
683     StructBinder {
684       M(pMethods,"p");
685     } _StructBinder;
686 #undef CurrentStruct
687 
688 #define CurrentStruct sqlite3_kvvfs_methods
689     StructBinder {
690       M(xRead,"i(sspi)");
691       M(xWrite,"i(sss)");
692       M(xDelete,"i(ss)");
693       M(nKeySize,"i");
694     } _StructBinder;
695 
696   } out( "]"/*structs*/);
697 
698   out("}"/*top-level object*/);
699   *zPos = 0;
700   aBuffer[0] = '{'/*end of the race-condition workaround*/;
701   return aBuffer;
702 #undef StructBinder
703 #undef StructBinder_
704 #undef StructBinder__
705 #undef M
706 #undef _StructBinder
707 #undef CloseBrace
708 #undef out
709 #undef outf
710 #undef lenCheck
711 }
712 
713 /*
714 ** This function is NOT part of the sqlite3 public API. It is strictly
715 ** for use by the sqlite project's own JS/WASM bindings.
716 **
717 ** This function invokes the xDelete method of the default VFS,
718 ** passing on the given filename. If zName is NULL, no default VFS is
719 ** found, or it has no xDelete method, SQLITE_MISUSE is returned, else
720 ** the result of the xDelete() call is returned.
721 */
722 WASM_KEEP
723 int sqlite3_wasm_vfs_unlink(const char * zName){
724   int rc = SQLITE_MISUSE /* ??? */;
725   sqlite3_vfs * const pVfs = sqlite3_vfs_find(0);
726 #if defined(__EMSCRIPTEN__)
727   emscripten_console_warn("sqlite3_wasm_vfs_unlink() will be removed.");
728 #endif
729   if( zName && pVfs && pVfs->xDelete ){
730     rc = pVfs->xDelete(pVfs, zName, 1);
731   }
732   return rc;
733 }
734 
735 /*
736 ** This function is NOT part of the sqlite3 public API. It is strictly
737 ** for use by the sqlite project's own JS/WASM bindings.
738 **
739 ** This function resets the given db pointer's database as described at
740 **
741 ** https://www.sqlite.org/c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase
742 **
743 ** Returns 0 on success, an SQLITE_xxx code on error. Returns
744 ** SQLITE_MISUSE if pDb is NULL.
745 */
746 WASM_KEEP
747 int sqlite3_wasm_db_reset(sqlite3*pDb){
748   int rc = SQLITE_MISUSE;
749   if( pDb ){
750     rc = sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
751     if( 0==rc ) rc = sqlite3_exec(pDb, "VACUUM", 0, 0, 0);
752     sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
753   }
754   return rc;
755 }
756 
757 /*
758 ** Uses the current database's VFS xRead to stream the db file's
759 ** contents out to the given callback. The callback gets a single
760 ** chunk of size n (its 2nd argument) on each call and must return 0
761 ** on success, non-0 on error. This function returns 0 on success,
762 ** SQLITE_NOTFOUND if no db is open, or propagates any other non-0
763 ** code from the callback. Note that this is not thread-friendly: it
764 ** expects that it will be the only thread reading the db file and
765 ** takes no measures to ensure that is the case.
766 **
767 ** This implementation appears to work fine, but
768 ** sqlite3_wasm_db_serialize() is arguably the better way to achieve
769 ** this.
770 */
771 WASM_KEEP
772 int sqlite3_wasm_db_export_chunked( sqlite3* pDb,
773                                     int (*xCallback)(unsigned const char *zOut, int n) ){
774   sqlite3_int64 nSize = 0;
775   sqlite3_int64 nPos = 0;
776   sqlite3_file * pFile = 0;
777   unsigned char buf[1024 * 8];
778   int nBuf = (int)sizeof(buf);
779   int rc = pDb
780     ? sqlite3_file_control(pDb, "main",
781                            SQLITE_FCNTL_FILE_POINTER, &pFile)
782     : SQLITE_NOTFOUND;
783   if( rc ) return rc;
784   rc = pFile->pMethods->xFileSize(pFile, &nSize);
785   if( rc ) return rc;
786   if(nSize % nBuf){
787     /* DB size is not an even multiple of the buffer size. Reduce
788     ** buffer size so that we do not unduly inflate the db size
789     ** with zero-padding when exporting. */
790     if(0 == nSize % 4096) nBuf = 4096;
791     else if(0 == nSize % 2048) nBuf = 2048;
792     else if(0 == nSize % 1024) nBuf = 1024;
793     else nBuf = 512;
794   }
795   for( ; 0==rc && nPos<nSize; nPos += nBuf ){
796     rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos);
797     if(SQLITE_IOERR_SHORT_READ == rc){
798       rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/;
799     }
800     if( 0==rc ) rc = xCallback(buf, nBuf);
801   }
802   return rc;
803 }
804 
805 /*
806 ** A proxy for sqlite3_serialize() which serializes the "main" schema
807 ** of pDb, placing the serialized output in pOut and nOut. nOut may be
808 ** NULL. If pDb or pOut are NULL then SQLITE_MISUSE is returned. If
809 ** allocation of the serialized copy fails, SQLITE_NOMEM is returned.
810 ** On success, 0 is returned and `*pOut` will contain a pointer to the
811 ** memory unless mFlags includes SQLITE_SERIALIZE_NOCOPY and the
812 ** database has no contiguous memory representation, in which case
813 ** `*pOut` will be NULL but 0 will be returned.
814 **
815 ** If `*pOut` is not NULL, the caller is responsible for passing it to
816 ** sqlite3_free() to free it.
817 */
818 WASM_KEEP
819 int sqlite3_wasm_db_serialize( sqlite3* pDb, unsigned char **pOut, sqlite3_int64 * nOut,
820                                unsigned int mFlags ){
821   unsigned char * z;
822   if( !pDb || !pOut ) return SQLITE_MISUSE;
823   if(nOut) *nOut = 0;
824   z = sqlite3_serialize(pDb, "main", nOut, mFlags);
825   if( z || (SQLITE_SERIALIZE_NOCOPY & mFlags) ){
826     *pOut = z;
827     return 0;
828   }else{
829     return SQLITE_NOMEM;
830   }
831 }
832 
833 /*
834 ** This function is NOT part of the sqlite3 public API. It is strictly
835 ** for use by the sqlite project's own JS/WASM bindings.
836 **
837 ** Allocates sqlite3KvvfsMethods.nKeySize bytes from
838 ** sqlite3_wasm_pstack_alloc() and returns 0 if that allocation fails,
839 ** else it passes that string to kvstorageMakeKey() and returns a
840 ** NUL-terminated pointer to that string. It is up to the caller to
841 ** use sqlite3_wasm_pstack_restore() to free the returned pointer.
842 */
843 WASM_KEEP
844 char * sqlite3_wasm_kvvfsMakeKeyOnPstack(const char *zClass,
845                                          const char *zKeyIn){
846   assert(sqlite3KvvfsMethods.nKeySize>24);
847   char *zKeyOut =
848     (char *)sqlite3_wasm_pstack_alloc(sqlite3KvvfsMethods.nKeySize);
849   if(zKeyOut){
850     kvstorageMakeKey(zClass, zKeyIn, zKeyOut);
851   }
852   return zKeyOut;
853 }
854 
855 /*
856 ** This function is NOT part of the sqlite3 public API. It is strictly
857 ** for use by the sqlite project's own JS/WASM bindings.
858 **
859 ** Returns the pointer to the singleton object which holds the kvvfs
860 ** I/O methods and associated state.
861 */
862 WASM_KEEP
863 sqlite3_kvvfs_methods * sqlite3_wasm_kvvfs_methods(void){
864   return &sqlite3KvvfsMethods;
865 }
866 
867 #if defined(__EMSCRIPTEN__) && defined(SQLITE_WASM_WASMFS)
868 #include <emscripten/wasmfs.h>
869 
870 /*
871 ** This function is NOT part of the sqlite3 public API. It is strictly
872 ** for use by the sqlite project's own JS/WASM bindings, specifically
873 ** only when building with Emscripten's WASMFS support.
874 **
875 ** This function should only be called if the JS side detects the
876 ** existence of the Origin-Private FileSystem (OPFS) APIs in the
877 ** client. The first time it is called, this function instantiates a
878 ** WASMFS backend impl for OPFS. On success, subsequent calls are
879 ** no-ops.
880 **
881 ** This function may be passed a "mount point" name, which must have a
882 ** leading "/" and is currently restricted to a single path component,
883 ** e.g. "/foo" is legal but "/foo/" and "/foo/bar" are not. If it is
884 ** NULL or empty, it defaults to "/persistent".
885 **
886 ** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend
887 ** object fails, SQLITE_IOERR if mkdir() of the zMountPoint dir in
888 ** the virtual FS fails. In builds compiled without SQLITE_WASM_WASMFS
889 ** defined, SQLITE_NOTFOUND is returned without side effects.
890 */
891 WASM_KEEP
892 int sqlite3_wasm_init_wasmfs(const char *zMountPoint){
893   static backend_t pOpfs = 0;
894   if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs";
895   if( !pOpfs ){
896     pOpfs = wasmfs_create_opfs_backend();
897     if( pOpfs ){
898       emscripten_console_log("Created WASMFS OPFS backend.");
899     }
900   }
901   /** It's not enough to instantiate the backend. We have to create a
902       mountpoint in the VFS and attach the backend to it. */
903   if( pOpfs && 0!=access(zMountPoint, F_OK) ){
904     /* mkdir() simply hangs when called from fiddle app. Cause is
905        not yet determined but the hypothesis is an init-order
906        issue. */
907     /* Note that this check and is not robust but it will
908        hypothetically suffice for the transient wasm-based virtual
909        filesystem we're currently running in. */
910     const int rc = wasmfs_create_directory(zMountPoint, 0777, pOpfs);
911     emscripten_console_logf("OPFS mkdir(%s) rc=%d", zMountPoint, rc);
912     if(rc) return SQLITE_IOERR;
913   }
914   return pOpfs ? 0 : SQLITE_NOMEM;
915 }
916 #else
917 WASM_KEEP
918 int sqlite3_wasm_init_wasmfs(const char *zUnused){
919   emscripten_console_warn("WASMFS OPFS is not compiled in.");
920   if(zUnused){/*unused*/}
921   return SQLITE_NOTFOUND;
922 }
923 #endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */
924 
925 #undef WASM_KEEP
926