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 "sqlite3.c" /* yes, .c instead of .h. */ 60 61 /* 62 ** WASM_KEEP is identical to EMSCRIPTEN_KEEPALIVE but is not 63 ** Emscripten-specific. It explicitly marks functions for export into 64 ** the target wasm file without requiring explicit listing of those 65 ** functions in Emscripten's -sEXPORTED_FUNCTIONS=... list (or 66 ** equivalent in other build platforms). Any function with neither 67 ** this attribute nor which is listed as an explicit export will not 68 ** be exported from the wasm file (but may still be used internally 69 ** within the wasm file). 70 ** 71 ** The functions in this file (sqlite3-wasm.c) which require exporting 72 ** are marked with this flag. They may also be added to any explicit 73 ** build-time export list but need not be. All of these APIs are 74 ** intended for use only within the project's own JS/WASM code, and 75 ** not by client code, so an argument can be made for reducing their 76 ** visibility by not including them in any build-time export lists. 77 ** 78 ** 2022-09-11: it's not yet _proven_ that this approach works in 79 ** non-Emscripten builds. If not, such builds will need to export 80 ** those using the --export=... wasm-ld flag (or equivalent). As of 81 ** this writing we are tied to Emscripten for various reasons 82 ** and cannot test the library with other build environments. 83 */ 84 #define WASM_KEEP __attribute__((used,visibility("default"))) 85 // See also: 86 //__attribute__((export_name("theExportedName"), used, visibility("default"))) 87 88 /* 89 ** This function is NOT part of the sqlite3 public API. It is strictly 90 ** for use by the sqlite project's own JS/WASM bindings. 91 ** 92 ** For purposes of certain hand-crafted C/Wasm function bindings, we 93 ** need a way of reporting errors which is consistent with the rest of 94 ** the C API, as opposed to throwing JS exceptions. To that end, this 95 ** internal-use-only function is a thin proxy around 96 ** sqlite3ErrorWithMessage(). The intent is that it only be used from 97 ** Wasm bindings such as sqlite3_prepare_v2/v3(), and definitely not 98 ** from client code. 99 ** 100 ** Returns err_code. 101 */ 102 WASM_KEEP 103 int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){ 104 if(0!=zMsg){ 105 const int nMsg = sqlite3Strlen30(zMsg); 106 sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg); 107 }else{ 108 sqlite3ErrorWithMsg(db, err_code, NULL); 109 } 110 return err_code; 111 } 112 113 /* 114 ** This function is NOT part of the sqlite3 public API. It is strictly 115 ** for use by the sqlite project's own JS/WASM bindings. Unlike the 116 ** rest of the sqlite3 API, this part requires C99 for snprintf() and 117 ** variadic macros. 118 ** 119 ** Returns a string containing a JSON-format "enum" of C-level 120 ** constants intended to be imported into the JS environment. The JSON 121 ** is initialized the first time this function is called and that 122 ** result is reused for all future calls. 123 ** 124 ** If this function returns NULL then it means that the internal 125 ** buffer is not large enough for the generated JSON. In debug builds 126 ** that will trigger an assert(). 127 */ 128 WASM_KEEP 129 const char * sqlite3_wasm_enum_json(void){ 130 static char strBuf[1024 * 12] = {0} /* where the JSON goes */; 131 int n = 0, childCount = 0, structCount = 0 132 /* output counters for figuring out where commas go */; 133 char * pos = &strBuf[1] /* skip first byte for now to help protect 134 ** against a small race condition */; 135 char const * const zEnd = pos + sizeof(strBuf) /* one-past-the-end */; 136 if(strBuf[0]) return strBuf; 137 /* Leave strBuf[0] at 0 until the end to help guard against a tiny 138 ** race condition. If this is called twice concurrently, they might 139 ** end up both writing to strBuf, but they'll both write the same 140 ** thing, so that's okay. If we set byte 0 up front then the 2nd 141 ** instance might return and use the string before the 1st instance 142 ** is done filling it. */ 143 144 /* Core output macros... */ 145 #define lenCheck assert(pos < zEnd - 128 \ 146 && "sqlite3_wasm_enum_json() buffer is too small."); \ 147 if(pos >= zEnd - 128) return 0 148 #define outf(format,...) \ 149 pos += snprintf(pos, ((size_t)(zEnd - pos)), format, __VA_ARGS__); \ 150 lenCheck 151 #define out(TXT) outf("%s",TXT) 152 #define CloseBrace(LEVEL) \ 153 assert(LEVEL<5); memset(pos, '}', LEVEL); pos+=LEVEL; lenCheck 154 155 /* Macros for emitting maps of integer- and string-type macros to 156 ** their values. */ 157 #define DefGroup(KEY) n = 0; \ 158 outf("%s\"" #KEY "\": {",(childCount++ ? "," : "")); 159 #define DefInt(KEY) \ 160 outf("%s\"%s\": %d", (n++ ? ", " : ""), #KEY, (int)KEY) 161 #define DefStr(KEY) \ 162 outf("%s\"%s\": \"%s\"", (n++ ? ", " : ""), #KEY, KEY) 163 #define _DefGroup CloseBrace(1) 164 165 /* The following groups are sorted alphabetic by group name. */ 166 DefGroup(access){ 167 DefInt(SQLITE_ACCESS_EXISTS); 168 DefInt(SQLITE_ACCESS_READWRITE); 169 DefInt(SQLITE_ACCESS_READ)/*docs say this is unused*/; 170 } _DefGroup; 171 172 DefGroup(blobFinalizers) { 173 /* SQLITE_STATIC/TRANSIENT need to be handled explicitly as 174 ** integers to avoid casting-related warnings. */ 175 out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1"); 176 } _DefGroup; 177 178 DefGroup(dataTypes) { 179 DefInt(SQLITE_INTEGER); 180 DefInt(SQLITE_FLOAT); 181 DefInt(SQLITE_TEXT); 182 DefInt(SQLITE_BLOB); 183 DefInt(SQLITE_NULL); 184 } _DefGroup; 185 186 DefGroup(encodings) { 187 /* Noting that the wasm binding only aims to support UTF-8. */ 188 DefInt(SQLITE_UTF8); 189 DefInt(SQLITE_UTF16LE); 190 DefInt(SQLITE_UTF16BE); 191 DefInt(SQLITE_UTF16); 192 /*deprecated DefInt(SQLITE_ANY); */ 193 DefInt(SQLITE_UTF16_ALIGNED); 194 } _DefGroup; 195 196 DefGroup(fcntl) { 197 DefInt(SQLITE_FCNTL_LOCKSTATE); 198 DefInt(SQLITE_FCNTL_GET_LOCKPROXYFILE); 199 DefInt(SQLITE_FCNTL_SET_LOCKPROXYFILE); 200 DefInt(SQLITE_FCNTL_LAST_ERRNO); 201 DefInt(SQLITE_FCNTL_SIZE_HINT); 202 DefInt(SQLITE_FCNTL_CHUNK_SIZE); 203 DefInt(SQLITE_FCNTL_FILE_POINTER); 204 DefInt(SQLITE_FCNTL_SYNC_OMITTED); 205 DefInt(SQLITE_FCNTL_WIN32_AV_RETRY); 206 DefInt(SQLITE_FCNTL_PERSIST_WAL); 207 DefInt(SQLITE_FCNTL_OVERWRITE); 208 DefInt(SQLITE_FCNTL_VFSNAME); 209 DefInt(SQLITE_FCNTL_POWERSAFE_OVERWRITE); 210 DefInt(SQLITE_FCNTL_PRAGMA); 211 DefInt(SQLITE_FCNTL_BUSYHANDLER); 212 DefInt(SQLITE_FCNTL_TEMPFILENAME); 213 DefInt(SQLITE_FCNTL_MMAP_SIZE); 214 DefInt(SQLITE_FCNTL_TRACE); 215 DefInt(SQLITE_FCNTL_HAS_MOVED); 216 DefInt(SQLITE_FCNTL_SYNC); 217 DefInt(SQLITE_FCNTL_COMMIT_PHASETWO); 218 DefInt(SQLITE_FCNTL_WIN32_SET_HANDLE); 219 DefInt(SQLITE_FCNTL_WAL_BLOCK); 220 DefInt(SQLITE_FCNTL_ZIPVFS); 221 DefInt(SQLITE_FCNTL_RBU); 222 DefInt(SQLITE_FCNTL_VFS_POINTER); 223 DefInt(SQLITE_FCNTL_JOURNAL_POINTER); 224 DefInt(SQLITE_FCNTL_WIN32_GET_HANDLE); 225 DefInt(SQLITE_FCNTL_PDB); 226 DefInt(SQLITE_FCNTL_BEGIN_ATOMIC_WRITE); 227 DefInt(SQLITE_FCNTL_COMMIT_ATOMIC_WRITE); 228 DefInt(SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE); 229 DefInt(SQLITE_FCNTL_LOCK_TIMEOUT); 230 DefInt(SQLITE_FCNTL_DATA_VERSION); 231 DefInt(SQLITE_FCNTL_SIZE_LIMIT); 232 DefInt(SQLITE_FCNTL_CKPT_DONE); 233 DefInt(SQLITE_FCNTL_RESERVE_BYTES); 234 DefInt(SQLITE_FCNTL_CKPT_START); 235 DefInt(SQLITE_FCNTL_EXTERNAL_READER); 236 DefInt(SQLITE_FCNTL_CKSM_FILE); 237 } _DefGroup; 238 239 DefGroup(flock) { 240 DefInt(SQLITE_LOCK_NONE); 241 DefInt(SQLITE_LOCK_SHARED); 242 DefInt(SQLITE_LOCK_RESERVED); 243 DefInt(SQLITE_LOCK_PENDING); 244 DefInt(SQLITE_LOCK_EXCLUSIVE); 245 } _DefGroup; 246 247 DefGroup(ioCap) { 248 DefInt(SQLITE_IOCAP_ATOMIC); 249 DefInt(SQLITE_IOCAP_ATOMIC512); 250 DefInt(SQLITE_IOCAP_ATOMIC1K); 251 DefInt(SQLITE_IOCAP_ATOMIC2K); 252 DefInt(SQLITE_IOCAP_ATOMIC4K); 253 DefInt(SQLITE_IOCAP_ATOMIC8K); 254 DefInt(SQLITE_IOCAP_ATOMIC16K); 255 DefInt(SQLITE_IOCAP_ATOMIC32K); 256 DefInt(SQLITE_IOCAP_ATOMIC64K); 257 DefInt(SQLITE_IOCAP_SAFE_APPEND); 258 DefInt(SQLITE_IOCAP_SEQUENTIAL); 259 DefInt(SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN); 260 DefInt(SQLITE_IOCAP_POWERSAFE_OVERWRITE); 261 DefInt(SQLITE_IOCAP_IMMUTABLE); 262 DefInt(SQLITE_IOCAP_BATCH_ATOMIC); 263 } _DefGroup; 264 265 DefGroup(openFlags) { 266 /* Noting that not all of these will have any effect in 267 ** WASM-space. */ 268 DefInt(SQLITE_OPEN_READONLY); 269 DefInt(SQLITE_OPEN_READWRITE); 270 DefInt(SQLITE_OPEN_CREATE); 271 DefInt(SQLITE_OPEN_URI); 272 DefInt(SQLITE_OPEN_MEMORY); 273 DefInt(SQLITE_OPEN_NOMUTEX); 274 DefInt(SQLITE_OPEN_FULLMUTEX); 275 DefInt(SQLITE_OPEN_SHAREDCACHE); 276 DefInt(SQLITE_OPEN_PRIVATECACHE); 277 DefInt(SQLITE_OPEN_EXRESCODE); 278 DefInt(SQLITE_OPEN_NOFOLLOW); 279 /* OPEN flags for use with VFSes... */ 280 DefInt(SQLITE_OPEN_MAIN_DB); 281 DefInt(SQLITE_OPEN_MAIN_JOURNAL); 282 DefInt(SQLITE_OPEN_TEMP_DB); 283 DefInt(SQLITE_OPEN_TEMP_JOURNAL); 284 DefInt(SQLITE_OPEN_TRANSIENT_DB); 285 DefInt(SQLITE_OPEN_SUBJOURNAL); 286 DefInt(SQLITE_OPEN_SUPER_JOURNAL); 287 DefInt(SQLITE_OPEN_WAL); 288 DefInt(SQLITE_OPEN_DELETEONCLOSE); 289 DefInt(SQLITE_OPEN_EXCLUSIVE); 290 } _DefGroup; 291 292 DefGroup(prepareFlags) { 293 DefInt(SQLITE_PREPARE_PERSISTENT); 294 DefInt(SQLITE_PREPARE_NORMALIZE); 295 DefInt(SQLITE_PREPARE_NO_VTAB); 296 } _DefGroup; 297 298 DefGroup(resultCodes) { 299 DefInt(SQLITE_OK); 300 DefInt(SQLITE_ERROR); 301 DefInt(SQLITE_INTERNAL); 302 DefInt(SQLITE_PERM); 303 DefInt(SQLITE_ABORT); 304 DefInt(SQLITE_BUSY); 305 DefInt(SQLITE_LOCKED); 306 DefInt(SQLITE_NOMEM); 307 DefInt(SQLITE_READONLY); 308 DefInt(SQLITE_INTERRUPT); 309 DefInt(SQLITE_IOERR); 310 DefInt(SQLITE_CORRUPT); 311 DefInt(SQLITE_NOTFOUND); 312 DefInt(SQLITE_FULL); 313 DefInt(SQLITE_CANTOPEN); 314 DefInt(SQLITE_PROTOCOL); 315 DefInt(SQLITE_EMPTY); 316 DefInt(SQLITE_SCHEMA); 317 DefInt(SQLITE_TOOBIG); 318 DefInt(SQLITE_CONSTRAINT); 319 DefInt(SQLITE_MISMATCH); 320 DefInt(SQLITE_MISUSE); 321 DefInt(SQLITE_NOLFS); 322 DefInt(SQLITE_AUTH); 323 DefInt(SQLITE_FORMAT); 324 DefInt(SQLITE_RANGE); 325 DefInt(SQLITE_NOTADB); 326 DefInt(SQLITE_NOTICE); 327 DefInt(SQLITE_WARNING); 328 DefInt(SQLITE_ROW); 329 DefInt(SQLITE_DONE); 330 // Extended Result Codes 331 DefInt(SQLITE_ERROR_MISSING_COLLSEQ); 332 DefInt(SQLITE_ERROR_RETRY); 333 DefInt(SQLITE_ERROR_SNAPSHOT); 334 DefInt(SQLITE_IOERR_READ); 335 DefInt(SQLITE_IOERR_SHORT_READ); 336 DefInt(SQLITE_IOERR_WRITE); 337 DefInt(SQLITE_IOERR_FSYNC); 338 DefInt(SQLITE_IOERR_DIR_FSYNC); 339 DefInt(SQLITE_IOERR_TRUNCATE); 340 DefInt(SQLITE_IOERR_FSTAT); 341 DefInt(SQLITE_IOERR_UNLOCK); 342 DefInt(SQLITE_IOERR_RDLOCK); 343 DefInt(SQLITE_IOERR_DELETE); 344 DefInt(SQLITE_IOERR_BLOCKED); 345 DefInt(SQLITE_IOERR_NOMEM); 346 DefInt(SQLITE_IOERR_ACCESS); 347 DefInt(SQLITE_IOERR_CHECKRESERVEDLOCK); 348 DefInt(SQLITE_IOERR_LOCK); 349 DefInt(SQLITE_IOERR_CLOSE); 350 DefInt(SQLITE_IOERR_DIR_CLOSE); 351 DefInt(SQLITE_IOERR_SHMOPEN); 352 DefInt(SQLITE_IOERR_SHMSIZE); 353 DefInt(SQLITE_IOERR_SHMLOCK); 354 DefInt(SQLITE_IOERR_SHMMAP); 355 DefInt(SQLITE_IOERR_SEEK); 356 DefInt(SQLITE_IOERR_DELETE_NOENT); 357 DefInt(SQLITE_IOERR_MMAP); 358 DefInt(SQLITE_IOERR_GETTEMPPATH); 359 DefInt(SQLITE_IOERR_CONVPATH); 360 DefInt(SQLITE_IOERR_VNODE); 361 DefInt(SQLITE_IOERR_AUTH); 362 DefInt(SQLITE_IOERR_BEGIN_ATOMIC); 363 DefInt(SQLITE_IOERR_COMMIT_ATOMIC); 364 DefInt(SQLITE_IOERR_ROLLBACK_ATOMIC); 365 DefInt(SQLITE_IOERR_DATA); 366 DefInt(SQLITE_IOERR_CORRUPTFS); 367 DefInt(SQLITE_LOCKED_SHAREDCACHE); 368 DefInt(SQLITE_LOCKED_VTAB); 369 DefInt(SQLITE_BUSY_RECOVERY); 370 DefInt(SQLITE_BUSY_SNAPSHOT); 371 DefInt(SQLITE_BUSY_TIMEOUT); 372 DefInt(SQLITE_CANTOPEN_NOTEMPDIR); 373 DefInt(SQLITE_CANTOPEN_ISDIR); 374 DefInt(SQLITE_CANTOPEN_FULLPATH); 375 DefInt(SQLITE_CANTOPEN_CONVPATH); 376 //DefInt(SQLITE_CANTOPEN_DIRTYWAL)/*docs say not used*/; 377 DefInt(SQLITE_CANTOPEN_SYMLINK); 378 DefInt(SQLITE_CORRUPT_VTAB); 379 DefInt(SQLITE_CORRUPT_SEQUENCE); 380 DefInt(SQLITE_CORRUPT_INDEX); 381 DefInt(SQLITE_READONLY_RECOVERY); 382 DefInt(SQLITE_READONLY_CANTLOCK); 383 DefInt(SQLITE_READONLY_ROLLBACK); 384 DefInt(SQLITE_READONLY_DBMOVED); 385 DefInt(SQLITE_READONLY_CANTINIT); 386 DefInt(SQLITE_READONLY_DIRECTORY); 387 DefInt(SQLITE_ABORT_ROLLBACK); 388 DefInt(SQLITE_CONSTRAINT_CHECK); 389 DefInt(SQLITE_CONSTRAINT_COMMITHOOK); 390 DefInt(SQLITE_CONSTRAINT_FOREIGNKEY); 391 DefInt(SQLITE_CONSTRAINT_FUNCTION); 392 DefInt(SQLITE_CONSTRAINT_NOTNULL); 393 DefInt(SQLITE_CONSTRAINT_PRIMARYKEY); 394 DefInt(SQLITE_CONSTRAINT_TRIGGER); 395 DefInt(SQLITE_CONSTRAINT_UNIQUE); 396 DefInt(SQLITE_CONSTRAINT_VTAB); 397 DefInt(SQLITE_CONSTRAINT_ROWID); 398 DefInt(SQLITE_CONSTRAINT_PINNED); 399 DefInt(SQLITE_CONSTRAINT_DATATYPE); 400 DefInt(SQLITE_NOTICE_RECOVER_WAL); 401 DefInt(SQLITE_NOTICE_RECOVER_ROLLBACK); 402 DefInt(SQLITE_WARNING_AUTOINDEX); 403 DefInt(SQLITE_AUTH_USER); 404 DefInt(SQLITE_OK_LOAD_PERMANENTLY); 405 //DefInt(SQLITE_OK_SYMLINK) /* internal use only */; 406 } _DefGroup; 407 408 DefGroup(serialize){ 409 DefInt(SQLITE_DESERIALIZE_FREEONCLOSE); 410 DefInt(SQLITE_DESERIALIZE_READONLY); 411 DefInt(SQLITE_DESERIALIZE_RESIZEABLE); 412 } _DefGroup; 413 414 DefGroup(syncFlags) { 415 DefInt(SQLITE_SYNC_NORMAL); 416 DefInt(SQLITE_SYNC_FULL); 417 DefInt(SQLITE_SYNC_DATAONLY); 418 } _DefGroup; 419 420 DefGroup(udfFlags) { 421 DefInt(SQLITE_DETERMINISTIC); 422 DefInt(SQLITE_DIRECTONLY); 423 DefInt(SQLITE_INNOCUOUS); 424 } _DefGroup; 425 426 DefGroup(version) { 427 DefInt(SQLITE_VERSION_NUMBER); 428 DefStr(SQLITE_VERSION); 429 DefStr(SQLITE_SOURCE_ID); 430 } _DefGroup; 431 432 #undef DefGroup 433 #undef DefStr 434 #undef DefInt 435 #undef _DefGroup 436 437 /* 438 ** Emit an array of "StructBinder" struct descripions, which look 439 ** like: 440 ** 441 ** { 442 ** "name": "MyStruct", 443 ** "sizeof": 16, 444 ** "members": { 445 ** "member1": {"offset": 0,"sizeof": 4,"signature": "i"}, 446 ** "member2": {"offset": 4,"sizeof": 4,"signature": "p"}, 447 ** "member3": {"offset": 8,"sizeof": 8,"signature": "j"} 448 ** } 449 ** } 450 ** 451 ** Detailed documentation for those bits are in the docs for the 452 ** Jaccwabyt JS-side component. 453 */ 454 455 /** Macros for emitting StructBinder description. */ 456 #define StructBinder__(TYPE) \ 457 n = 0; \ 458 outf("%s{", (structCount++ ? ", " : "")); \ 459 out("\"name\": \"" # TYPE "\","); \ 460 outf("\"sizeof\": %d", (int)sizeof(TYPE)); \ 461 out(",\"members\": {"); 462 #define StructBinder_(T) StructBinder__(T) 463 /** ^^^ indirection needed to expand CurrentStruct */ 464 #define StructBinder StructBinder_(CurrentStruct) 465 #define _StructBinder CloseBrace(2) 466 #define M(MEMBER,SIG) \ 467 outf("%s\"%s\": " \ 468 "{\"offset\":%d,\"sizeof\": %d,\"signature\":\"%s\"}", \ 469 (n++ ? ", " : ""), #MEMBER, \ 470 (int)offsetof(CurrentStruct,MEMBER), \ 471 (int)sizeof(((CurrentStruct*)0)->MEMBER), \ 472 SIG) 473 474 structCount = 0; 475 out(", \"structs\": ["); { 476 477 #define CurrentStruct sqlite3_vfs 478 StructBinder { 479 M(iVersion,"i"); 480 M(szOsFile,"i"); 481 M(mxPathname,"i"); 482 M(pNext,"p"); 483 M(zName,"s"); 484 M(pAppData,"p"); 485 M(xOpen,"i(pppip)"); 486 M(xDelete,"i(ppi)"); 487 M(xAccess,"i(ppip)"); 488 M(xFullPathname,"i(ppip)"); 489 M(xDlOpen,"p(pp)"); 490 M(xDlError,"p(pip)"); 491 M(xDlSym,"p()"); 492 M(xDlClose,"v(pp)"); 493 M(xRandomness,"i(pip)"); 494 M(xSleep,"i(pi)"); 495 M(xCurrentTime,"i(pp)"); 496 M(xGetLastError,"i(pip)"); 497 M(xCurrentTimeInt64,"i(pp)"); 498 M(xSetSystemCall,"i(ppp)"); 499 M(xGetSystemCall,"p(pp)"); 500 M(xNextSystemCall,"p(pp)"); 501 } _StructBinder; 502 #undef CurrentStruct 503 504 #define CurrentStruct sqlite3_io_methods 505 StructBinder { 506 M(iVersion,"i"); 507 M(xClose,"i(p)"); 508 M(xRead,"i(ppij)"); 509 M(xWrite,"i(ppij)"); 510 M(xTruncate,"i(pj)"); 511 M(xSync,"i(pi)"); 512 M(xFileSize,"i(pp)"); 513 M(xLock,"i(pi)"); 514 M(xUnlock,"i(pi)"); 515 M(xCheckReservedLock,"i(pp)"); 516 M(xFileControl,"i(pip)"); 517 M(xSectorSize,"i(p)"); 518 M(xDeviceCharacteristics,"i(p)"); 519 M(xShmMap,"i(piiip)"); 520 M(xShmLock,"i(piii)"); 521 M(xShmBarrier,"v(p)"); 522 M(xShmUnmap,"i(pi)"); 523 M(xFetch,"i(pjip)"); 524 M(xUnfetch,"i(pjp)"); 525 } _StructBinder; 526 #undef CurrentStruct 527 528 #define CurrentStruct sqlite3_file 529 StructBinder { 530 M(pMethods,"p"); 531 } _StructBinder; 532 #undef CurrentStruct 533 534 } out( "]"/*structs*/); 535 536 out("}"/*top-level object*/); 537 *pos = 0; 538 strBuf[0] = '{'/*end of the race-condition workaround*/; 539 return strBuf; 540 #undef StructBinder 541 #undef StructBinder_ 542 #undef StructBinder__ 543 #undef M 544 #undef _StructBinder 545 #undef CloseBrace 546 #undef out 547 #undef outf 548 #undef lenCheck 549 } 550 551 /* 552 ** This function is NOT part of the sqlite3 public API. It is strictly 553 ** for use by the sqlite project's own JS/WASM bindings. 554 ** 555 ** This function invokes the xDelete method of the default VFS, 556 ** passing on the given filename. If zName is NULL, no default VFS is 557 ** found, or it has no xDelete method, SQLITE_MISUSE is returned, else 558 ** the result of the xDelete() call is returned. 559 */ 560 WASM_KEEP 561 int sqlite3_wasm_vfs_unlink(const char * zName){ 562 int rc = SQLITE_MISUSE /* ??? */; 563 sqlite3_vfs * const pVfs = sqlite3_vfs_find(0); 564 if( zName && pVfs && pVfs->xDelete ){ 565 rc = pVfs->xDelete(pVfs, zName, 1); 566 } 567 return rc; 568 } 569 570 #if defined(__EMSCRIPTEN__) 571 #include <emscripten/console.h> 572 #if defined(SQLITE_WASM_WASMFS) 573 #include <emscripten/wasmfs.h> 574 575 /* 576 ** This function is NOT part of the sqlite3 public API. It is strictly 577 ** for use by the sqlite project's own JS/WASM bindings, specifically 578 ** only when building with Emscripten's WASMFS support. 579 ** 580 ** This function should only be called if the JS side detects the 581 ** existence of the Origin-Private FileSystem (OPFS) APIs in the 582 ** client. The first time it is called, this function instantiates a 583 ** WASMFS backend impl for OPFS. On success, subsequent calls are 584 ** no-ops. 585 ** 586 ** This function may be passed a "mount point" name, which must have a 587 ** leading "/" and is currently restricted to a single path component, 588 ** e.g. "/foo" is legal but "/foo/" and "/foo/bar" are not. If it is 589 ** NULL or empty, it defaults to "/persistent". 590 ** 591 ** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend 592 ** object fails, SQLITE_IOERR if mkdir() of the zMountPoint dir in 593 ** the virtual FS fails. In builds compiled without SQLITE_WASM_WASMFS 594 ** defined, SQLITE_NOTFOUND is returned without side effects. 595 */ 596 WASM_KEEP 597 int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ 598 static backend_t pOpfs = 0; 599 if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs"; 600 if( !pOpfs ){ 601 pOpfs = wasmfs_create_opfs_backend(); 602 if( pOpfs ){ 603 emscripten_console_log("Created WASMFS OPFS backend."); 604 } 605 } 606 /** It's not enough to instantiate the backend. We have to create a 607 mountpoint in the VFS and attach the backend to it. */ 608 if( pOpfs && 0!=access(zMountPoint, F_OK) ){ 609 /* mkdir() simply hangs when called from fiddle app. Cause is 610 not yet determined but the hypothesis is an init-order 611 issue. */ 612 /* Note that this check and is not robust but it will 613 hypothetically suffice for the transient wasm-based virtual 614 filesystem we're currently running in. */ 615 const int rc = wasmfs_create_directory(zMountPoint, 0777, pOpfs); 616 emscripten_console_logf("OPFS mkdir(%s) rc=%d", zMountPoint, rc); 617 if(rc) return SQLITE_IOERR; 618 } 619 return pOpfs ? 0 : SQLITE_NOMEM; 620 } 621 #else 622 WASM_KEEP 623 int sqlite3_wasm_init_wasmfs(const char *zUnused){ 624 emscripten_console_warn("WASMFS OPFS is not compiled in."); 625 if(zUnused){/*unused*/} 626 return SQLITE_NOTFOUND; 627 } 628 #endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */ 629 #endif 630 631 #undef WASM_KEEP 632