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