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