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