Compare commits

..

62 Commits

Author SHA1 Message Date
drh 6b783ec950 Pervent the parser stack from growing to be larger than 100 plus four times
the SQLITE_LIMIT_EXPR_DEPTH setting.

FossilOrigin-Name: 5728129e5432500550096e2a1350897881f0379b49b60faf49481c505b1eb323
2025-11-18 02:24:46 +00:00
stephan 847d2ed685 Add api.oo1=0 flag to ext/wasm/GNUmakefile to strip out the sqlite3.oo1 pieces from the build. Part of the ongoing response to [forum:4b7d45433731d2e0|forum post 4b7d45433731d2e0].
FossilOrigin-Name: ea48567ac54e4949a8b68977a58a5de7946e074ae8737133071d02f40ac97f34
2025-11-17 23:55:41 +00:00
drh 18a9bdd90a Fix a harmless compiler warning.
FossilOrigin-Name: 6621737cc05cbf8ff5f576775a8a3c64f666b56d42939968ebb55d72a835646b
2025-11-17 19:19:58 +00:00
stephan 3e2ecc390b Remove an unused struct.
FossilOrigin-Name: 93dd0e62b74a0d99803f680f23953e9fa2429074505ba402ca5ed4610ddef8fb
2025-11-15 16:06:03 +00:00
stephan a1dede1e58 JNI: when validing the eTextRep argument in sqlite3_create_function(), only validate the lower four bits (the high bits are for other flags). Add flags to test functions to ensure this case is triggered.
FossilOrigin-Name: aab640be7bc5829fe16d2582b13f942b7debb271c150ca2471561de6b2d70dc7
2025-11-15 15:30:45 +00:00
stephan 982274b8e9 Replace the JNI binding's internal use of sqlite3ErrorWithMsg() with sqlite3_set_errmsg() and have it handle OOM in a way consistent with the rest of the JNI bindings.
FossilOrigin-Name: 0899a9eb3af727f310372f3441573ab506ffec31dca4774e850b2b59a4001ee0
2025-11-15 15:09:04 +00:00
stephan e83ffd5c87 Random JS build cleanups and parallel build mkdir race fixes. Reinstate the recently-removed [a65bd978cbc646ec] after finding a reformulation which works on Emscripten 4.0.19 (and saves about 85kb on the JS deliverables).
FossilOrigin-Name: acb1525a49463de67716638626406ccde9a282907d0de218ab88bf474ba830ee
2025-11-15 13:30:13 +00:00
stephan 393a4d8ac5 Reorder initialization of sqlite3ApiBootstrap()'s bownstrapped config object so that it's possible to inject the wasm memory and exports via that, to simplify plugging-in of sqlite3-api.js in other builds. Previously the build-provided wasm exports/memory overrode any which a client might want to use.
FossilOrigin-Name: 2bd0addb6068cd2b34f6151a824c578e2253f541a8c55b578219b09c42afd82b
2025-11-15 11:53:30 +00:00
stephan 987870a6a0 Generic internal JS cleanups towards improving portability of sqlite3-api.js to other build systems.
FossilOrigin-Name: 5bc37e5c2fcd83fd0bc40234144072363f1cbf7d811a15b74a0991e397a35eb8
2025-11-15 11:30:45 +00:00
stephan a804a65617 Move sqlite3-api-cleanup.js into post-js-footer.js to remove the final direct Emscripten dependency from the intermediary build product sqlite3-api.js (the whole library, waiting to be bootstrapped). This is partly in response to [forum:4b7d45433731d2e0|forum post 4b7d45433731d2e0], which demonstrates a potential use case for a standalone sqlite3-api.js. This is a build/doc change, not a functional one.
FossilOrigin-Name: 2fcbd8e17d8f1dd7e9d45168805dba718777e46803d9375a4212296d3d0cd89c
2025-11-15 09:19:03 +00:00
stephan 5279cbd353 API doc typo fix.
FossilOrigin-Name: c1e9791fbf9e4c2ca6f9f031ea2c26d8b4bfb4d54850a53853f2b2d9620792ef
2025-11-15 08:05:12 +00:00
drh c14ae9cd3b New interfaces sqlite3_str_truncate() and sqlite3_str_free(). Version number
increases to 3.52.0.

FossilOrigin-Name: fa85534ed927851dc37a4943e83259bff4509f141449226ffb506f9acc7b2cc5
2025-11-14 20:09:01 +00:00
dan ed7981ea3e If SQLITE_EXPERIMENTAL_PRAGMA_20251114 is defined at build-time, send an experimental pragma file-control to the VFS if a call to take a SHARED lock is to be immediately followed by one to take a RESERVED.
FossilOrigin-Name: e2b3f1a9480a9be3e06c2d79abcf39f399b5adf2ca882841b3b3fa199c239dd8
2025-11-14 17:27:20 +00:00
stephan e1f7ec65fd Slight restructure of the previous checkin.
FossilOrigin-Name: 8ff98747c072c8c333b1b37cf4ec9344e84f081bd4e6d3b5e75f37b1e1ce9e84
2025-11-14 17:23:24 +00:00
stephan 505d8a43db In sqlite3-api-cleanup.js, if no Emscripten module is detected then simply return, rather than throw. This should enable the generated sqliet3-api.js (normally an intermediary file) to be used as-is, with the caveat that the caller has to bootstrap the library themselves.
FossilOrigin-Name: d64c9cd4c7a1ffe04de6c75126563d7bbb24266e13d41406f6d55720b8199037
2025-11-14 16:56:51 +00:00
stephan 408c991017 Remove a harmless duplicated makefile var assignment from mkwasmbuilds.c.
FossilOrigin-Name: 4b4a6fbe20d51689e0abc65beed078bbb9418383e69eb8ec13f0657e2cf13bfd
2025-11-14 15:03:55 +00:00
stephan 09cc9b5184 Fix a makefile ordering bug which caused certain builds to fail unless others had already been built. Remove the superfluous sqlite3-node.wasm from the final deliverables dir (sqlite3-node.mjs uses sqlite3.wasm instead).
FossilOrigin-Name: fd70088284946b9d4315781b3f68133cc0abd4244247f2fce04044feab8a97c0
2025-11-14 14:42:00 +00:00
drh 9bafbd122b Fix a harmless compiler warning in testing code.
FossilOrigin-Name: 5252a2e629e1adb61169d32ca6458c6decd1ec562f358bb9d0b448a2f0243c56
2025-11-14 11:02:49 +00:00
dan 7a796b702f A better fix for the issue with RETURNING triggers on eponymous virtual tables and SQLITE_SCHEMA errors first addressed by [45d820ca22].
FossilOrigin-Name: bf399992cb98e5d5f002a90b521328d5c2f113ebab8601653452d78222077bde
2025-11-13 20:37:09 +00:00
dan 8b34ce7d61 Add an OOM test case for the issue with dropping RETURNING triggers when the schema is reset while preparing a statement that uses an eponymous vtab.
FossilOrigin-Name: dc569288dd63754269e14be7a9937c882531685a3e9caec25f86ec8c01eb9583
2025-11-13 18:02:22 +00:00
dan 826bebdb31 Add better test case for the issue with dropping RETURNING triggers when the schema is reset while preparing a statement.
FossilOrigin-Name: 6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3
2025-11-13 17:42:55 +00:00
stephan 388c1da56e Generic makefile cleanups and doc updates.
FossilOrigin-Name: e8b34b4178be621102dac165b716283055fad90b3edc2394f56a24f9f0149448
2025-11-13 17:37:40 +00:00
stephan 9e6474c5a8 Internal doc fix (renamed file).
FossilOrigin-Name: cb8fb01fe19ba3af536a662aed894b2b0eb2463c8d34c644c498234fd82122f3
2025-11-13 16:38:45 +00:00
stephan 319870836c JS code reformatting and doc updates. No functional changes.
FossilOrigin-Name: c566c653e4f55afa0660e819ed5b1fd96cb9b24bc78c333adcd8825331a9dd26
2025-11-13 15:33:44 +00:00
stephan a9025a5f1a Add the #include -raw flag to ext/wasm/c-pp-lite.c to support a pending feature.
FossilOrigin-Name: 42c30c314969c0f2573bbe36615683ac19a7ba4e30004c7080873459096caaf5
2025-11-13 14:47:41 +00:00
drh 237778289b Fix a problem in the EXISTS-to-JOIN optimization ([e33da6d5dc964db8]) so
that it works with nested WHERE and EXISTS statements.
[forum:/forumpost/0704c3c41e49631b|Forum post 0704c3c41e4]

FossilOrigin-Name: d1e901eddc25175174d0706238ae0c33bfa5569e0c2ba4f1164b7a9600203442
2025-11-13 11:36:48 +00:00
stephan 57a533a7c3 mkwasmbuilds.c doc updates. Merge in the parts of [8611cf643b] which are not contentious.
FossilOrigin-Name: cb0f0e22241aae65938b4bc7a1b809088466a17cee80344f66ee889a76c422c1
2025-11-13 09:03:48 +00:00
stephan f47095a5a0 Teach c-pp to export its argv as a #define list so that we can embed it in the generates files.
FossilOrigin-Name: 42f95ea71e5e7e927685de3a6da2ede38abe7cabdd1fc71b9a14bebe9f54a65e
2025-11-13 08:26:11 +00:00
stephan 791b767b26 Doc typo fix reported in [forum:00e49e9aa1|forum post 00e49e9aa1].
FossilOrigin-Name: 36cd33f634a45900f6e52ba07aa20242a5f2b29c7cbe19be968c52ffef34fcde
2025-11-13 07:07:28 +00:00
stephan ce53b80819 Minor doc correction and a JS error message tweak.
FossilOrigin-Name: c4ae21c89e5fd40eefd4916df6c6a6c4e27075a434a9d47576d3fcfbc7720588
2025-11-13 06:49:12 +00:00
stephan b867030b1a Clarify that 'pikchr' is not a typo.
FossilOrigin-Name: d7bb2ee6ec23c266c887fb2aeb77b0b17cd8f1429564d341537f57c5478410e2
2025-11-12 17:25:17 +00:00
drh 7efded5edc Improved concurrency for "make devtest" by splitting fuzzdata1.db and
fuzzdata2.db into slices for asan and ubsan testing.

FossilOrigin-Name: 2c31176607f02a73cf2626cda2dd0711ae74bdf0b4520d4c84ff299c860e419e
2025-11-10 20:01:39 +00:00
dan f07576429e Avoid dropping RETURNING triggers when the schema is reset while preparing a statement.
FossilOrigin-Name: 45d820ca227eb1ade4dda498b0f94b2c5df4bab3fc5fcdd517ee125a43d16f4d
2025-11-10 19:11:15 +00:00
dan 14fcb8252a Avoid dropping RETURNING triggers when the schema is reset while preparing a statement.
FossilOrigin-Name: e26bcef7522a6f6ee8d55fa30e7fe06419566cf4e8c2df0c33c92a4c89f58c05
2025-11-10 17:37:59 +00:00
drh a79f685533 Fix a missing va_end() call in the intckMprintf() function of the
incremental integrity-check extension.

FossilOrigin-Name: 62ad2350e368dc337ba2d0fb6847d07c40a6f79520dd6414d22b5b54983b0b12
2025-11-10 11:05:36 +00:00
dan 240397bb03 A more compact fix for the problem first fixed by [5f5a736f88].
FossilOrigin-Name: 7a644178c8d289ca18631844b2d73b32fddc72afcc80906633dd38c14eba2ca9
2025-11-10 11:00:41 +00:00
dan 4ac766cc05 Have sqlite3_set_errmsg() return SQLITE_MISUSE if a NULL db handle is passed to it, as documented.
FossilOrigin-Name: 5f5a736f88bc9bc6c9c83d2cbfd74c0b5357d7417d9993d34a78f0b7317ff796
2025-11-10 10:47:29 +00:00
stephan 73caea1764 Reworking of JS internals to support binding of nested C structs (like sqlite3_index_constraint and friends) and allow some of the automated JS/C conversions to be plugged in at the struct-binding level, simplifying how struct members, in particular function pointers, can be used from JS.
FossilOrigin-Name: bb4fd5b789cebf2b224c29023fea3e620a86fb36730c36c0d85d9f35880bf643
2025-11-10 07:41:54 +00:00
drh 998ebf1de7 Fix the ".www" command of the CLI so that it works on unix systems with
newer web browsers that do not allow access to files in /tmp.

FossilOrigin-Name: 2f918c14bac28c567cc854b3d41dcdd59191a118bb5fdea9373945fe860161f5
2025-11-10 01:46:06 +00:00
stephan 051e942f5d Minor doc typo fix reported in [forum:939d5864df|forum post 939d5864df].
FossilOrigin-Name: a1f9c977b83fab11c54710070dbedfaea47195050946db74075bdd3ade97a4c8
2025-11-09 07:11:15 +00:00
stephan 4182294987 CLI shell: ensure that .dump propagates its error code on error. Problem reported in [forum:a4f3873b0a8503cc|forum post a4f3873b0a].
FossilOrigin-Name: 850b92b6347187d702736bf5a574b9b4a49854a33799875f24fc75c50a6bf908
2025-11-09 06:51:32 +00:00
stephan c55d8262cf In sqlite3.wasm.allocFromTypedArray(), swap the order of the allocation and the access to the heap view object to work around an obscure issue when allocating huge blobs. The heap view object could previously become stale via the following allocation if the underlying WebAssembly.Memory object needed to grow. Essentially a realloc()-moves-the-pointer situation but it only comes up with huge allocations under the right circumstances and would trigger a JS exception (as opposed to corrupting the WASM heap). Problem reported in [forum:05b77273be104532|forum post 05b77273be104532].
FossilOrigin-Name: 0f712b6b0516dc151d3bcbb63497661c82e11eae368e639bbdf197e1b3467195
2025-11-09 06:32:10 +00:00
stephan 66b37e991b Add some UNUSED_PARAMATER()s for the sake of -pedantic -DSQLITE_OMIT_WAL.
FossilOrigin-Name: 620434a4a276ecaf2ee56d325815ac4e33c95e1190b420a341e376e54ef60278
2025-11-07 11:46:56 +00:00
drh 0aca0ccf2c Fix a harmless static-analyzer warning.
FossilOrigin-Name: 9819fc5aa7706fda9d4ec67835ae87eed64d321672873c9d864788b8cf5d27d8
2025-11-07 11:22:47 +00:00
drh 748c0adb62 Get the sqlite3Hwtime() function working on ARM. Enable scanstatus by
default on Windows CLI builds.

FossilOrigin-Name: 305bb022368bac9fafd7c2794762299324796903aaea270923d07f2127d8926c
2025-11-06 13:19:50 +00:00
drh e77530050e Improvements to documentation for stmt_scanstatus interfaces.
FossilOrigin-Name: 5f3e883d180d6fb7a1909df284713170f5431ea7afcc1a3eb5912c4620df42b2
2025-11-06 12:25:26 +00:00
stephan 366e0ed80c JNI: doc tweaks. Add missing SQLITE_DBSTATUS_TEMPBUF_SPILL export.
FossilOrigin-Name: 2c8938f43f721a2592b0efe36f75ab87aa370654e1a22d646c0a17d58d643295
2025-11-05 10:07:57 +00:00
stephan 201066302e TEA extension: add --tcl-stubs config flag, defaulting to zero, because there does not seem to be a universally-valid default for that. Addresses [forum:cd6503fce2|forum post cd6503fce2].
FossilOrigin-Name: 4954b94763052ed60ad2ae610e4f5c18fdba4475a39eb369408e984c89805e97
2025-11-05 05:59:53 +00:00
drh 29bdac3ee5 Remove stale code from the fileio.c extension.
FossilOrigin-Name: d26f115760f16cac1cd28c950d1c0eec199461d2c9a52baafb91ff6b8d5ec151
2025-11-04 23:47:49 +00:00
stephan 53ba0b80f2 Minor wasm build simplifications and extend the JS bindings of sqlite3_column/value_text() such that they include embeded NUL bytes in their result strings rather than truncate them at NUL. Consolidate the shell.c build flags from the canonical and autoconf makefiles into the configure script.
FossilOrigin-Name: cee2e2576f5e91911a019bff025ee6071850c0d75941e8746f10d57b56bd830a
2025-11-04 22:01:55 +00:00
stephan b799156a31 Consolidate the three VFS-specific SEE tests into a shared routine.
FossilOrigin-Name: 8ac0bf125ddb6cc86a6825dcfe8895559835eca85ef14b5ad489f7c8159462e4
2025-11-04 01:03:58 +00:00
stephan 23e4ae2121 Move the hard-coded SHELL_OPT makefile values from the two main makefiles into their shared configure script.
FossilOrigin-Name: 900885c4fb3071e461bf868e9e68d0d8f3d3e83a1bcbf5c9c68179c701c1fb92
2025-11-04 00:15:51 +00:00
stephan abc23b5404 Merge trunk into wasm-post-3.51 to for some minor config script work.
FossilOrigin-Name: bf55a4220a74022e8be5f8a0cd7f4ca395a36e1666e14113e7e60c4a94cf0b3a
2025-11-04 00:10:10 +00:00
stephan e977440d79 Add tests demonstrating [d0e803b90344].
FossilOrigin-Name: 7d22ee947ddecb0dc6c640e79c9a09c0931f8b04f97d3ac89afdbf1736312bf7
2025-11-03 21:38:34 +00:00
stephan bb3b269ba9 Add new file missing from [936990cf067a5ebb] (and subsequently deleted by fossil clean -x). Have speedtest1 wasm use the user-provided sqlite3.c, rather than forcing the canonical one, so that the wasm exports don't have to be re-generated for that special case. Remove a harmless duplicate -D... flag.
FossilOrigin-Name: 7a592f5cd09699b45051855f6d477def40220b17642cbdb0f35ed74dd32becf1
2025-11-03 21:26:27 +00:00
stephan c129de05bb Simplify the EXPORTED_FUNCTIONS lists to use the preprocessor instead of per-list shell commands. (Unrelated) Remove part of the post-compilation JS filtering which breaks with emsdk 4.0.16+, which means the .js files are about 57kb bigger than they really ought to be.
FossilOrigin-Name: 936990cf067a5ebb34f7f662fc2d23d468c50f179afafe47fe0d2ed775f5ef74
2025-10-30 20:18:20 +00:00
stephan 6acd8d28fd Merge trunk into the wasm-post-3.51 branch.
FossilOrigin-Name: dda1735716cf1006b2a5d1d8eb29df3039047be38dcc04249c4ce50c77084fac
2025-10-30 19:32:46 +00:00
stephan bc5e0be7f8 A experiment addressing the embedded-NUL behavior of sqlite3_colum/value_text() in the JS bindings, as discussed in [forum:d77281aec2df9ada|forum post d77281aec2]. This is an experiment only. It works, in that existing tests do not see the difference, but it has implicications which require careful consideration before deploying.
FossilOrigin-Name: d0e803b90344ee972e4b3fb30b77e283599dc4d5c6a3335ce9fea653a1b3f6f0
2025-10-30 02:21:38 +00:00
stephan 241004f8fc Demonstrate the opfs-sahpool VFS with SEE.
FossilOrigin-Name: b4cffc00f3a18906867e8f070fbc49293ac5c038bad58e96ea74948591f31013
2025-10-26 21:45:02 +00:00
stephan 89a9efe840 Add a test which uses SEE via the "opfs" VFS. "opfs-sahpool" is pending.
FossilOrigin-Name: 1eb5a7ea394aa5b7e8594d73ce31f4b9bef55f2fa977dc26810c0bfba1cc39f7
2025-10-26 21:30:29 +00:00
stephan 4f177f1d3e Merge trunk into the wasm-post-3.51 branch.
FossilOrigin-Name: be5d2bae508a681628d4f84528e37db4e8a39b16e580b0d6ab4cd844566e973f
2025-10-26 18:43:04 +00:00
stephan 02c5f3976f Random tiny tweaks in internal JS and flesh out the tester1 test selection list to include both 32-/64-bit entries for all tester1XYZ.html combinations. For after the 3.51 release.
FossilOrigin-Name: c087a1d23deac84ac46e769332ec167c5b38fc8e525fd90484d3fa0b6d304ffa
2025-10-24 21:01:23 +00:00
58 changed files with 1656 additions and 1557 deletions
+1
View File
@@ -1770,6 +1770,7 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_PERCENTILE=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_STRICT_SUBTYPE=1
!ENDIF
+1 -1
View File
@@ -1 +1 @@
3.51.1
3.52.0
-13
View File
@@ -117,19 +117,6 @@ sqlite_cfg.h: $(AS_AUTO_DEF)
# CFLAGS for sqlite3$(T.exe)
#
SHELL_OPT ?= @OPT_SHELL@
SHELL_OPT += -DSQLITE_DQS=0
SHELL_OPT += -DSQLITE_ENABLE_FTS4
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_PERCENTILE
SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1
#
# Library-level feature flags
+19 -1
View File
@@ -557,7 +557,25 @@ proc proc-debug {msg} {
}
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app
#
# OPT_SHELL = feature-related CFLAGS for the sqlite3 CLI app. The
# list's initial values are defaults which are always applied and not
# affected by --feature-flags. The list is appended to by various
# --feature-flags.
define OPT_SHELL {
-DSQLITE_DQS=0
-DSQLITE_ENABLE_FTS4
-DSQLITE_ENABLE_RTREE
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
-DSQLITE_ENABLE_STMTVTAB
-DSQLITE_ENABLE_DBPAGE_VTAB
-DSQLITE_ENABLE_DBSTAT_VTAB
-DSQLITE_ENABLE_BYTECODE_VTAB
-DSQLITE_ENABLE_OFFSET_SQL_FUNC
-DSQLITE_ENABLE_PERCENTILE
-DSQLITE_STRICT_SUBTYPE=1
}
########################################################################
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is
# -shell then it strips that arg and passes the remaining args the
+22 -7
View File
@@ -695,6 +695,7 @@ other than that, the order of directives in Lemon is arbitrary.</p>
<li><tt><a href='#parse_failure'>%parse_failure</a></tt>
<li><tt><a href='#pright'>%right</a></tt>
<li><tt><a href='#reallc'>%realloc</a></tt>
<li><tt><a href='#reallc'>%reallocx</a></tt>
<li><tt><a href='#stack_overflow'>%stack_overflow</a></tt>
<li><tt><a href='#stack_size'>%stack_size</a></tt>
<li><tt><a href='#start_symbol'>%start_symbol</a></tt>
@@ -1203,15 +1204,29 @@ the wildcard token and some other token, the other token is always used.
The wildcard token is only matched if there are no alternatives.</p>
<a id='reallc'></a>
<h4>4.4.26 The <tt>%realloc</tt> and <tt>%free</tt> directives</h4>
<h4>4.4.26 The <tt>%realloc</tt>, <tt>%reallocx</tt>,
and <tt>%free</tt> directives</h4>
<p>The <tt>%realloc</tt> and <tt>%free</tt> directives defines function
that allocate and free heap memory. The signatures of these functions
should be the same as the realloc() and free() functions from the standard
C library.
<p>The <tt>%realloc</tt>, <tt>%reallocx</tt>, and <tt>%free</tt>
directives defines function that allocate and free heap memory.
The signatures of th3 %realloc and %free are the same as
realloc() and free() functions from the standard C library.
The %reallocx function has the same semantics as %realloc but
takes four parameters instead of two:
<ol>
<li> A pointer to the space to be reallocated, or NULL for a new allocation,
<li> The number of elements to allocate,
<li> The size of each element,
<li> The %extra parameter.
</ol>
The extra parameters of %reallocx can be used, for example, to monitor
the parser stack size and raise an error if it exceeds application-defined
limits.
If both %reallocx and %realloc are defined, then %reallocx is used
and %realloc is ignored.
<p>If both of these functions are defined
then these functions are used to allocate and free
<p>If %free is defined and one of %realloc and %reallocx is
defined then the functions are used to allocate and free
memory for supplemental parser stack space, if the initial
parse stack space is exceeded. The initial parser stack size
is specified by either <tt>%stack_size</tt> or the
-1
View File
@@ -2074,7 +2074,6 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
while( 1 ){
u64 iDelta = 0;
if( i>=n ) break;
if( eDetail==FTS5_DETAIL_NONE ){
/* todo */
if( i<n && a[i]==0 ){
-11
View File
@@ -396,12 +396,7 @@ static int fts5VocabOpenMethod(
return rc;
}
/*
** Restore cursor pCsr to the state it was in immediately after being
** created by the xOpen() method.
*/
static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
int nCol = pCsr->pFts5->pConfig->nCol;
pCsr->rowid = 0;
sqlite3Fts5IterClose(pCsr->pIter);
sqlite3Fts5StructureRelease(pCsr->pStruct);
@@ -411,12 +406,6 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
pCsr->nLeTerm = -1;
pCsr->zLeTerm = 0;
pCsr->bEof = 0;
pCsr->iCol = 0;
pCsr->iInstPos = 0;
pCsr->iInstOff = 0;
pCsr->colUsed = 0;
memset(pCsr->aCnt, 0, sizeof(i64)*nCol);
memset(pCsr->aDoc, 0, sizeof(i64)*nCol);
}
/*
-362
View File
@@ -16124,367 +16124,5 @@ do_catchsql_test 83.1 {
SELECT * FROM t1('R*R*R*R*R*R*R*R*') WHERE (a,b)<=(current_date,0 BETWEEN 'a'<>11 AND '') ORDER BY rowid DESC;
} {/.*fts5: corruption found/}
#-------------------------------------------------------------------------
reset_db
do_test 84.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 53248 pagesize 4096 filename c1a.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 0d .....@ ........
| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
| 3488: 32 74 32 0d 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
| 4032: 28 61 2c 62 2c 63 29 00 00 00 39 00 00 00 00 00 (a,b,c)...9.....
| page 3 offset 8192
| 0: 05 00 00 00 02 0f f1 00 00 00 00 0c 0f fb 0f f1 ................
| 4064: 00 00 0b 01 03 00 1c 81 3a 84 5e 81 3a 81 3a 0a ........:.^.:.:.
| 4080: 0a 00 00 00 0b 84 80 80 80 80 01 00 00 00 0a 0a ................
| page 4 offset 12288
| 0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
| page 7 offset 24576
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 10 offset 36864
| 0: 0d 00 00 00 02 0f e2 00 0f e2 0f ef 00 00 00 00 ................
| 4064: 00 00 0b 01 03 00 1c 81 3a 84 5e 81 3a 81 3a 0f ........:.^.:.:.
| 4080: 0a 03 00 24 00 00 00 00 01 01 02 00 01 01 01 09 ...$............
| page 11 offset 40960
| 0: 0d 00 00 00 01 00 22 00 00 22 00 00 00 00 00 00 ................
| 32: 00 00 9f 56 84 80 80 80 80 01 04 00 bf 30 00 00 ...V.........0..
| 48: 0f 58 02 30 30 19 02 05 01 02 05 01 02 05 16 02 .X.00...........
| 64: 05 01 02 05 01 02 05 61 02 05 01 02 05 01 02 05 .......a........
| 80: 13 02 05 01 02 05 01 02 05 0d 02 03 01 02 03 01 ................
| 96: 02 03 02 09 78 66 66 66 66 66 66 66 65 81 17 02 ....xfffffffe...
| 112: 05 01 02 05 01 02 05 01 01 31 04 02 04 01 02 04 .........1......
| 128: 01 02 04 01 02 05 01 02 05 01 02 05 0d 02 06 01 ................
| 144: 02 06 01 02 06 02 01 30 79 02 04 01 02 04 01 02 .......0y.......
| 160: 04 03 02 30 30 2b 02 05 01 02 05 01 02 05 58 02 ...00+........X.
| 176: 05 01 02 05 01 02 05 01 02 05 01 02 05 01 02 05 ................
| 192: 16 02 05 01 02 05 01 02 05 05 06 30 30 30 30 30 ...........00000
| 208: 30 81 0b 02 04 01 02 04 01 02 04 10 02 05 01 02 0...............
| 224: 05 01 02 05 03 02 32 34 76 02 05 01 02 05 01 02 ......24v.......
| 240: 05 02 01 38 07 02 04 01 02 04 01 02 04 01 01 32 ...8...........2
| 256: 28 02 04 01 02 04 01 02 04 04 02 05 01 02 05 01 (...............
| 272: 02 05 02 01 30 1f 02 05 01 02 05 01 02 05 03 02 ....0...........
| 288: 30 30 10 02 05 01 02 05 01 02 05 6a 02 04 01 02 00.........j....
| 304: 04 01 02 04 02 08 35 30 30 30 30 30 30 30 81 26 ......50000000.&
| 320: 02 05 01 02 05 01 02 05 01 01 33 07 02 06 01 02 ..........3.....
| 336: 06 01 02 06 81 2c 02 04 01 02 04 01 02 04 02 04 .....,..........
| 352: 32 37 36 36 81 23 02 05 01 02 05 01 02 05 01 01 2766.#..........
| 368: 34 13 02 05 01 02 05 01 02 05 02 03 30 39 36 1c 4...........096.
| 384: 02 05 01 02 05 01 02 05 07 02 05 01 02 05 01 02 ................
| 400: 05 01 03 35 30 30 7f 02 05 01 02 05 01 02 05 04 ...500..........
| 416: 02 30 30 81 0e 02 06 01 02 06 01 02 06 06 03 30 .00............0
| 432: 30 30 81 11 02 04 01 02 04 01 02 04 01 05 36 35 00............65
| 448: 35 33 36 81 1a 02 05 01 02 05 01 02 05 01 04 38 536............8
| 464: 31 39 32 81 02 02 06 01 02 06 01 02 06 01 05 61 192............a
| 480: 6c 6c 6f 77 01 02 02 01 02 02 01 02 02 02 02 72 llow...........r
| 496: 67 81 08 02 04 01 02 04 01 02 04 02 05 74 6f 6d g............tom
| 512: 69 63 04 02 02 01 02 02 01 02 02 03 06 74 61 63 ic...........tac
| 528: 68 65 64 79 02 03 01 02 03 01 02 03 02 0d 75 74 hedy..........ut
| 544: 6f 63 68 65 63 6b 70 6f 69 6e 74 2b 02 04 01 02 ocheckpoint+....
| 560: 04 01 02 04 05 06 76 61 63 75 75 6d 0d 02 03 01 ......vacuum....
| 576: 02 03 01 02 03 01 06 62 69 6e 61 72 79 03 06 01 .......binary...
| 592: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 608: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 624: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 640: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 656: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 672: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 688: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 704: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 720: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 736: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 752: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 768: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 784: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 800: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 816: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 832: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 848: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 864: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 880: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 896: 01 02 02 02 07 79 74 65 63 6f 64 65 37 02 03 01 .....ytecode7...
| 912: 02 03 01 02 03 01 05 63 61 63 68 65 10 02 03 01 .......cache....
| 928: 02 03 01 01 03 02 04 6c 61 6e 67 07 02 03 01 02 .......lang.....
| 944: 03 01 02 03 02 05 6f 6c 75 6d 6e 7c 02 03 01 02 ......olumn|....
| 960: 03 01 02 03 03 06 6d 6d 65 6e 74 73 43 02 04 01 ......mmentsC...
| 976: 02 04 01 02 04 04 05 70 69 6c 65 72 07 02 02 01 .......piler....
| 992: 02 02 01 02 02 05 04 6f 75 6e 64 7f 02 03 01 02 .......ound.....
| 1008: 03 01 02 03 03 03 75 6e 74 81 17 02 04 01 02 04 ......unt.......
| 1024: 01 02 04 02 05 75 72 73 6f 72 3a 02 03 01 02 03 .....ursor:.....
| 1040: 01 02 03 01 06 64 62 70 61 67 65 3d 02 03 01 02 .....dbpage=....
| 1056: 03 01 02 03 03 04 73 74 61 74 40 02 03 01 02 03 ......stat@.....
| 1072: 01 02 03 02 04 65 62 75 67 0a 02 02 01 02 02 01 .....ebug.......
| 1088: 02 02 03 05 66 61 75 6c 74 0d 02 02 01 02 02 01 ....fault.......
| 1104: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1120: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1136: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1152: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1168: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1184: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1200: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 4f 02 ..............O.
| 1216: 03 01 02 03 01 02 03 03 03 70 74 68 81 05 02 04 .........pth....
| 1232: 01 02 04 01 02 04 19 02 04 01 02 04 01 02 04 02 ................
| 1248: 05 69 72 65 63 74 34 02 02 01 02 02 01 02 02 01 .irect4.........
| 1264: 06 65 6e 61 62 6c 65 37 02 02 01 02 02 01 02 02 .enable7........
| 1280: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1296: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1312: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1328: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1344: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1360: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1376: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1392: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1408: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1424: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1440: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1456: 02 01 02 02 02 06 78 70 6c 61 69 6e 43 02 03 01 ......xplainC...
| 1472: 02 03 01 02 03 04 01 72 81 05 02 03 01 02 03 01 .......r........
| 1488: 02 03 03 07 74 65 6e 73 69 6f 6e 81 2f 02 04 01 ....tension./...
| 1504: 02 04 01 02 04 01 04 66 69 6c 65 13 02 03 01 02 .......file.....
| 1520: 03 01 02 03 02 05 6f 72 6d 61 74 13 02 04 01 02 ......ormat.....
| 1536: 04 01 02 04 02 03 74 73 33 46 02 03 01 02 03 01 ......ts3F......
| 1552: 02 03 01 02 03 01 02 03 01 02 03 04 01 34 4c 02 .............4L.
| 1568: 03 01 02 03 01 02 03 04 01 35 4f 02 03 01 02 03 .........5O.....
| 1584: 01 02 03 02 03 75 6e 63 5e 02 05 01 02 05 01 02 .....unc^.......
| 1600: 05 05 04 74 69 6f 6e 73 02 05 01 02 05 01 02 05 ...tions........
| 1616: 13 02 03 01 02 03 01 02 03 09 01 73 55 02 04 01 ...........sU...
| 1632: 02 04 01 02 04 01 07 67 65 6f 70 6f 6c 79 52 02 .......geopolyR.
| 1648: 03 01 02 03 01 02 03 01 05 68 69 6e 74 73 3a 02 .........hints:.
| 1664: 04 01 02 04 01 02 04 02 03 6f 6f 6b 61 02 04 01 .........ooka...
| 1680: 02 04 01 02 04 01 02 69 6e 01 02 04 01 02 04 01 .......in.......
| 1696: 02 04 03 04 69 74 73 7a 1f 02 04 01 02 04 01 02 ....itsz........
| 1712: 04 03 08 74 72 69 6e 73 69 63 73 04 02 03 01 02 ...trinsics.....
| 1728: 03 01 02 03 01 07 6a 6f 75 72 6e 61 6c 16 02 03 ......journal...
| 1744: 01 02 03 01 02 03 01 06 6c 65 6e 67 74 68 81 0b ........length..
| 1760: 02 03 01 02 03 01 02 03 01 02 05 01 02 05 01 02 ................
| 1776: 05 0d 02 04 01 02 04 01 02 04 02 03 69 6b 65 81 ............ike.
| 1792: 0e 02 03 01 02 03 01 02 03 03 03 6d 69 74 16 02 ...........mit..
| 1808: 05 01 02 05 01 02 05 5e 02 04 01 02 04 01 02 04 .......^........
| 1824: 02 03 6f 61 64 81 2f 02 03 01 02 03 01 02 03 01 ..oad./.........
| 1840: 06 6d 61 6c 6c 6f 63 76 02 02 01 02 02 01 02 02 .mallocv........
| 1856: 3a 02 03 01 02 03 01 02 03 03 02 74 68 55 02 03 :..........thU..
| 1872: 01 02 03 01 02 03 03 01 78 79 02 02 01 02 02 01 ........xy......
| 1888: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1904: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1920: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1936: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 1952: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 1968: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 1984: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 2000: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 2016: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 2032: 02 02 02 05 65 6d 6f 72 79 81 11 02 03 01 02 03 ....emory.......
| 2048: 01 02 03 04 04 73 79 73 35 58 02 03 01 02 03 01 .....sys5X......
| 2064: 02 03 02 03 6d 61 70 19 02 03 01 02 03 01 02 03 ....map.........
| 2080: 79 02 03 01 02 03 01 02 03 02 04 75 74 65 78 81 y..........utex.
| 2096: 2c 02 02 01 02 02 01 02 02 01 06 6e 6f 63 61 73 ,..........nocas
| 2112: 65 02 06 01 02 02 03 06 01 02 02 03 06 01 02 02 e...............
| 2128: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2144: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2160: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2176: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2192: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2208: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2224: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2240: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2256: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2272: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2288: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2304: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2320: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2336: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2352: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2368: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2384: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2400: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2416: 02 02 03 06 01 02 02 03 07 72 6d 61 6c 69 7a 65 .........rmalize
| 2432: 5b 02 03 01 02 03 01 02 03 02 05 75 6d 62 65 72 [..........umber
| 2448: 81 23 02 04 01 02 04 01 02 04 01 06 6f 66 66 73 .#..........offs
| 2464: 65 74 5e 02 03 01 02 03 01 02 03 02 03 6d 69 74 et^..........mit
| 2480: 81 2c 02 03 01 02 03 01 02 03 01 02 02 01 02 02 .,..............
| 2496: 01 02 02 02 01 70 81 26 02 04 01 02 04 01 02 04 .....p.&........
| 2512: 02 07 76 65 72 66 6c 6f 77 34 02 03 01 02 03 01 ..verflow4......
| 2528: 02 03 01 04 70 61 67 65 1c 02 03 01 02 03 01 02 ....page........
| 2544: 03 64 02 04 01 02 04 01 02 04 13 02 03 01 02 03 .d..............
| 2560: 01 02 03 01 02 03 01 02 03 01 02 03 03 09 72 65 ..............re
| 2576: 6e 74 68 65 73 69 73 49 02 04 01 02 04 01 02 04 nthesisI........
| 2592: 03 05 74 74 65 72 6e 81 0e 02 04 01 02 04 01 02 ..ttern.........
| 2608: 04 02 05 63 61 63 68 65 1f 02 03 01 02 03 01 02 ...cache........
| 2624: 03 02 08 72 65 75 70 64 61 74 65 61 02 03 01 02 ...reupdatea....
| 2640: 03 01 02 03 01 04 72 65 61 64 34 02 04 01 02 04 ......read4.....
| 2656: 01 02 04 03 07 63 75 72 73 69 76 65 22 02 03 01 .....cursive....
| 2672: 02 03 01 02 03 02 04 6f 77 69 64 01 02 03 01 02 .......owid.....
| 2688: 03 01 02 03 02 04 74 72 65 65 64 02 03 01 02 03 ......treed.....
| 2704: 01 02 03 04 02 69 6d 01 06 01 02 02 03 06 01 02 .....im.........
| 2720: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2736: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2752: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2768: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2784: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2800: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2816: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2832: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2848: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2864: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2880: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2896: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2912: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 2928: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 2944: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 2960: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 2976: 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 ................
| 2992: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 3008: 01 02 02 03 06 01 02 02 03 06 01 02 02 01 0a 73 ...............s
| 3024: 63 61 6e 73 74 61 74 75 73 70 02 04 01 02 04 01 canstatusp......
| 3040: 02 04 02 05 65 63 74 6f 72 25 02 03 01 02 03 01 ....ector%......
| 3056: 02 03 03 04 6c 65 63 74 7f 02 04 01 02 04 01 02 ....lect........
| 3072: 04 03 05 73 73 69 6f 6e 67 02 03 01 02 03 01 02 ...ssiong.......
| 3088: 03 02 03 69 7a 65 10 02 04 01 02 04 01 02 04 04 ...ize..........
| 3104: 02 04 01 02 04 01 02 04 01 02 04 01 02 04 01 02 ................
| 3120: 04 01 02 04 01 02 04 01 02 04 07 02 04 01 02 04 ................
| 3136: 01 02 04 5b 02 05 01 02 05 01 02 05 10 02 04 01 ...[............
| 3152: 02 04 01 02 04 04 02 04 01 02 04 01 02 04 02 03 ................
| 3168: 6f 66 74 76 02 03 01 02 03 01 02 03 02 02 71 6c oftv..........ql
| 3184: 5e 02 04 01 02 04 01 02 04 13 02 04 01 02 04 01 ^...............
| 3200: 02 04 28 02 03 01 02 03 01 02 03 02 04 74 61 74 ..(..........tat
| 3216: 34 6a 02 03 01 02 03 01 02 03 03 02 6d 74 70 02 4j..........mtp.
| 3232: 03 01 02 03 01 02 03 05 04 76 74 61 62 6d 02 03 .........vtabm..
| 3248: 01 02 03 01 02 03 03 03 6f 72 65 81 35 02 03 01 ........ore.5...
| 3264: 02 03 01 02 03 02 0a 79 6e 63 68 72 6f 6e 6f 75 .......ynchronou
| 3280: 73 28 02 03 01 02 03 01 02 03 04 02 04 01 02 04 s(..............
| 3296: 01 02 04 03 04 73 74 65 6d 81 32 02 02 01 02 02 .....stem.2.....
| 3312: 01 02 02 01 04 74 65 6d 70 81 35 02 02 01 02 02 .....temp.5.....
| 3328: 01 02 02 02 06 68 72 65 61 64 73 31 02 04 01 02 .....hreads1....
| 3344: 04 01 02 04 76 02 04 01 02 04 01 02 04 08 03 61 ....v..........a
| 3360: 66 65 81 38 02 02 01 02 02 01 02 02 02 06 72 69 fe.8..........ri
| 3376: 67 67 65 72 81 20 02 03 01 02 03 01 02 03 08 01 gger. ..........
| 3392: 73 22 02 04 01 02 04 01 02 04 01 07 75 6e 6b 6e s...........unkn
| 3408: 6f 77 6e 73 02 03 01 02 03 01 02 03 01 08 76 61 owns..........va
| 3424: 72 69 61 62 6c 65 81 23 02 03 01 02 03 01 02 03 riable.#........
| 3440: 02 03 64 62 65 81 26 02 03 01 02 03 01 02 03 02 ..dbe.&.........
| 3456: 03 69 65 77 01 02 05 01 02 05 01 02 05 02 03 74 .iew...........t
| 3472: 61 62 37 02 04 01 02 04 01 02 04 04 02 04 01 02 ab7.............
| 3488: 04 01 02 04 01 02 04 01 02 04 01 02 04 01 03 77 ...............w
| 3504: 61 6c 2b 02 03 01 02 03 01 02 03 01 02 03 01 02 al+.............
| 3520: 03 01 02 03 02 05 6f 72 6b 65 72 31 02 03 01 02 ......orker1....
| 3536: 03 01 02 03 76 02 03 01 02 03 01 02 03 01 01 78 ....v..........x
| 3552: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3568: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3584: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3600: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3616: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3632: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3648: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3664: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3680: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3696: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3712: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3728: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3744: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3760: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3776: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3792: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3808: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3824: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3840: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3856: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3872: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3888: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3904: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3920: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3936: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3952: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3968: 06 01 01 02 01 06 04 30 15 1e 0c 28 1b 0d 0c 15 .......0...(....
| 3984: 0c 16 14 16 10 0c 17 0e 0e 0f 11 10 10 0e 10 11 ................
| 4000: 18 11 82 3e 12 10 0f 10 11 10 0f 0f 10 11 0f 0f ...>............
| 4016: 81 05 18 10 81 45 11 0d 13 0f 10 17 0c 0c 0e 18 .....E..........
| 4032: 0c 12 10 0e 0d 0f 13 12 24 0f 17 0f 1a 0d 81 1c ........$.......
| 4048: 11 0f 17 10 82 3e 12 11 11 18 0d 12 2a 14 11 10 .....>......*...
| 4064: 13 0f 12 0f 0f 82 3a 15 10 0f 10 4d 0e 1f 0f 0d ......:....M....
| 4080: 0f 0f 1e 10 10 1a 0f 12 0c 12 14 0f 0e 20 17 19 ............. ..
| page 12 offset 45056
| 0: 0d 00 00 00 01 0d f4 00 0d f4 00 00 00 00 00 00 ................
| 3568: 00 00 00 00 84 04 84 80 80 80 80 02 04 00 88 0c ................
| 3584: 00 07 02 00 01 01 02 56 06 01 01 02 01 06 01 01 .......V........
| 3600: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3616: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3632: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3648: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3664: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3680: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3696: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3712: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3728: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3744: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3760: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3776: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3792: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3808: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3824: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3840: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3856: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3872: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3888: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3904: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3920: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3936: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3952: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3968: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3984: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4000: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 4016: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 4032: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 4048: 52 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 R...............
| 4064: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4080: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| end c1a.txt.db
}]} {}
do_catchsql_test 84.1 {
SELECT * FROM t1('R*R*x') ORDER BY rowid DESC;
} {1 {fts5: corruption found reading blob 137438953475 from table "t1"}}
sqlite3_fts5_may_be_corrupt 0
finish_test
-22
View File
@@ -305,28 +305,6 @@ do_catchsql_test 6.2 {
sqlite3_fts5_may_be_corrupt 0
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, col);
INSERT INTO t1 VALUES('xx', 'xx');
CREATE TABLE x1(t);
INSERT INTO x1 VALUES('xx');
INSERT INTO x1 VALUES('xx');
SELECT term, col FROM v1;
} {
xx a xx b
}
do_execsql_test 7.1 {
SELECT * FROM x1 WHERE 'a'=(SELECT col FROM v1 WHERE term=t)
} {xx xx}
finish_test
+19 -16
View File
@@ -13,11 +13,14 @@ Technical support is available in the forum:
<https://sqlite.org/forum>
> **FOREWARNING:** this subproject is very much in development and
subject to any number of changes. Please do not rely on any
information about its API until this disclaimer is removed. The JNI
bindings released with version 3.43 are a "tech preview." Once
finalized, strong backward compatibility guarantees will apply.
> **FOREWARNING:** the JNI subproject is experimental and subject to
any number of changes. This API is "feature-complete", with only a
few difficult-to-reach corners of the C API not represented here,
but it is not a supported deliverable of the project so does not
have same backward compatibility guarantees which the C APIs
do. That said: the [C-style API](#1to1ish) is especially resistent
to compatibility breakage because it's designed to be as close to
the C API as feasible.
Project goals/requirements:
@@ -162,11 +165,13 @@ or propagate exceptions and must return error information (if any) via
result codes or `null`. The only cases where the C-style APIs may
throw is through client-side misuse, e.g. passing in a null where it
may cause a `NullPointerException`. The APIs clearly mark function
parameters which should not be null, but does not generally actively
defend itself against such misuse. Some C-style APIs explicitly accept
`null` as a no-op for usability's sake, and some of the JNI APIs
deliberately return an error code, instead of segfaulting, when passed
a `null`.
parameters which should not be null, and it internally uses the
`SQLITE_API_ARMOR` mechanism to help product against such misuse. Some
C-style APIs explicitly accept `null` as a no-op for usability's sake,
and some of the JNI APIs deliberately return an error code, instead of
segfaulting, when passed a `null`. There are no known cases where it
will misuse memory if passed a `null` or out-of-range value from
client code.
Client-defined callbacks _must never throw exceptions_ unless _very
explicitly documented_ as being throw-safe. Exceptions are generally
@@ -194,7 +199,8 @@ Some constructs, when modelled 1-to-1 from C to Java, are unduly
clumsy to work with in Java because they try to shoehorn C's way of
doing certain things into Java's wildly different ways. The following
subsections cover those, starting with a verbose explanation and
demonstration of where such changes are "really necessary"...
demonstration of where such changes are "really necessary" for
usability's sake...
### Custom Collations
@@ -286,12 +292,9 @@ binding. The Java API has only one core function-registration function:
```java
int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
int encoding, SQLFunction func);
int flags, SQLFunction func);
```
> Design question: does the encoding argument serve any purpose in
Java? That's as-yet undetermined. If not, it will be removed.
`SQLFunction` is not used directly, but is instead instantiated via
one of its three subclasses:
@@ -313,4 +316,4 @@ in-flux nature of this API.
Various APIs which accept callbacks, e.g. `sqlite3_trace_v2()` and
`sqlite3_update_hook()`, use interfaces similar to those shown above.
Despite the changes in signature, the JNI layer makes every effort to
provide the same semantics as the C API documentation suggests.
provide the same semantics as the C API documentation describes.
+43 -51
View File
@@ -133,11 +133,9 @@
** Which sqlite3.c we're using needs to be configurable to enable
** building against a custom copy, e.g. the SEE variant. We have to
** include sqlite3.c, as opposed to sqlite3.h, in order to get access
** to some internal details like SQLITE_MAX_... and friends. This
** increases the rebuild time considerably but we need this in order
** to access some internal functionality and keep the to-Java-exported
** values of SQLITE_MAX_... and SQLITE_LIMIT_... in sync with the C
** build.
** to some internal details like SQLITE_MAX_... and friends, and keep
** those consistent with this build. This increases the rebuild time
** considerably, however.
*/
#ifndef SQLITE_C
# define SQLITE_C sqlite3.c
@@ -335,7 +333,7 @@ struct S3JniNphOp {
const char * const zMember /* Name of member property */;
const char * const zTypeSig /* JNI type signature of zMember */;
/*
** klazz is a global ref to the class represented by pRef.
** klazz is a global ref to the class represented by zName.
**
** According to:
**
@@ -999,19 +997,20 @@ static S3JniEnv * S3JniEnv__get(JNIEnv * const env){
** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not
** from client code.
**
** Returns err_code.
** Returns err_code _unless_ err_code is 0 and sqlite3_set_errmsg()
** fails with OOM, in which case it may return SQLITE_OOM or fail
** fatally.
**
** This function predates sqlite3_set_errmsg(), which is why it has a
** slightly different interface. Before that function was introduced,
** this code used the SQLite-internal APIs to do this.
*/
static int s3jni_db_error(sqlite3* const db, int err_code,
const char * const zMsg){
static int s3jni_db_error(JNIEnv * env, sqlite3* const db,
int err_code, const char * const zMsg){
if( db!=0 ){
if( 0==zMsg ){
sqlite3Error(db, err_code);
}else{
const int nMsg = sqlite3Strlen30(zMsg);
sqlite3_mutex_enter(sqlite3_db_mutex(db));
sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg);
sqlite3_mutex_leave(sqlite3_db_mutex(db));
}
int const rc = sqlite3_set_errmsg(db, err_code, zMsg);
s3jni_oom_fatal(0==rc);
if( rc && !err_code ) err_code=rc;
}
return err_code;
}
@@ -1235,11 +1234,11 @@ static int s3jni__db_exception(JNIEnv * const env, sqlite3 * const pDb,
char * zMsg;
S3JniExceptionClear;
zMsg = s3jni_exception_error_msg(env, ex);
s3jni_db_error(pDb, errCode, zMsg ? zMsg : zDfltMsg);
s3jni_db_error(env, pDb, errCode, zMsg ? zMsg : zDfltMsg);
sqlite3_free(zMsg);
S3JniUnrefLocal(ex);
}else if( zDfltMsg ){
s3jni_db_error(pDb, errCode, zDfltMsg);
s3jni_db_error(env, pDb, errCode, zDfltMsg);
}
return errCode;
}
@@ -1956,15 +1955,6 @@ static void S3JniUdf_finalizer(void * s){
S3JniUdf_free(s3jni_env(), (S3JniUdf*)s, 1);
}
/*
** Helper for processing args to UDF handlers with signature
** (sqlite3_context*,int,sqlite3_value**).
*/
typedef struct {
jobject jcx /* sqlite3_context */;
jobjectArray jargv /* sqlite3_value[] */;
} udf_jargs;
/*
** Converts the given (cx, argc, argv) into arguments for the given
** UDF, writing the result (Java wrappers for cx and argv) in the
@@ -2006,7 +1996,7 @@ error_oom:
/*
** Requires that jCx and jArgv are sqlite3_context
** resp. array-of-sqlite3_value values initialized by udf_args(). The
** latter will be 0-and-NULL for UDF types with no arguments. This
** (argc,argv) are (0,NULL) for UDF types with no arguments. This
** function zeroes out the nativePointer member of jCx and each entry
** in jArgv. This is a safety-net precaution to avoid undefined
** behavior if a Java-side UDF holds a reference to its context or one
@@ -2099,19 +2089,19 @@ static int udf_xFSI(sqlite3_context* const pCx, int argc,
sqlite3_value** const argv, S3JniUdf * const s,
jmethodID xMethodID, const char * const zFuncType){
S3JniDeclLocal_env;
udf_jargs args = {0,0};
int rc = udf_args(env, pCx, argc, argv, &args.jcx, &args.jargv);
jobject jcx = 0 /* sqlite3_context */;
jobjectArray jargv = 0 /* sqlite3_value[] */;
int rc = udf_args(env, pCx, argc, argv, &jcx, &jargv);
if( 0 == rc ){
(*env)->CallVoidMethod(env, s->jObj, xMethodID, args.jcx, args.jargv);
(*env)->CallVoidMethod(env, s->jObj, xMethodID, jcx, jargv);
S3JniIfThrew{
rc = udf_report_exception(env, 'F'==zFuncType[1]/*xFunc*/, pCx,
s->zFuncName, zFuncType);
}
udf_unargs(env, args.jcx, argc, args.jargv);
udf_unargs(env, jcx, argc, jargv);
}
S3JniUnrefLocal(args.jcx);
S3JniUnrefLocal(args.jargv);
S3JniUnrefLocal(jcx);
S3JniUnrefLocal(jargv);
return rc;
}
@@ -3300,7 +3290,7 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
S3JniDb_mutex_enter;
ps = S3JniDb_from_jlong(jpDb);
if( !ps ){
s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0);
s3jni_db_error(env, ps->pDb, SQLITE_MISUSE, 0);
S3JniDb_mutex_leave;
return 0;
}
@@ -3320,13 +3310,14 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
else sqlite3_rollback_hook(ps->pDb, 0, 0);
}else{
jclass const klazz = (*env)->GetObjectClass(env, jHook);
jmethodID const xCallback = (*env)->GetMethodID(env, klazz, "call",
isCommit ? "()I" : "()V");
jmethodID const xCallback =
(*env)->GetMethodID(env, klazz, "call",
isCommit ? "()I" : "()V");
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionReport;
S3JniExceptionClear;
s3jni_db_error(ps->pDb, SQLITE_ERROR,
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching call() method in"
"hook object.");
}else{
@@ -3606,7 +3597,7 @@ S3JniApi(sqlite3_create_collation() sqlite3_create_collation_v2(),
(*env)->GetMethodID(env, klazz, "call", "([B[B)I");
S3JniUnrefLocal(klazz);
S3JniIfThrew{
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Could not get call() method from "
"CollationCallback object.");
}else{
@@ -3645,15 +3636,15 @@ S3JniApi(sqlite3_create_function() sqlite3_create_function_v2()
if( !pDb || !jFuncName ){
return SQLITE_MISUSE;
}else if( !encodingTypeIsValid(eTextRep) ){
return s3jni_db_error(pDb, SQLITE_FORMAT,
}else if( !encodingTypeIsValid(eTextRep & 0x0f) ){
return s3jni_db_error(env, pDb, SQLITE_FORMAT,
"Invalid function encoding option.");
}
s = S3JniUdf_alloc(env, jFunctor);
if( !s ) return SQLITE_NOMEM;
if( UDF_UNKNOWN_TYPE==s->type ){
rc = s3jni_db_error(pDb, SQLITE_MISUSE,
rc = s3jni_db_error(env, pDb, SQLITE_MISUSE,
"Cannot unambiguously determine function type.");
S3JniUdf_free(env, s, 1);
goto error_cleanup;
@@ -4012,7 +4003,7 @@ S3JniApi(sqlite3_jni_db_error(), jint, 1jni_1db_1error)(
zStr = jStr
? s3jni_jstring_to_utf8( jStr, 0)
: NULL;
rc = s3jni_db_error( ps->pDb, (int)jRc, zStr );
rc = s3jni_db_error(env, ps->pDb, (int)jRc, zStr );
sqlite3_free(zStr);
}
return rc;
@@ -4321,7 +4312,7 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId,
jTable = jDbName ? s3jni_utf8_to_jstring( zTable, -1) : 0;
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
s3jni_db_error(env, ps->pDb, SQLITE_NOMEM, 0);
}else{
assert( hook.jObj );
assert( hook.midCallback );
@@ -4423,7 +4414,7 @@ static jobject s3jni_updatepre_hook(JNIEnv * env, int isPre, jlong jpDb, jobject
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(ps->pDb, SQLITE_ERROR,
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching callback on "
"(pre)update hook object.");
}else{
@@ -4532,7 +4523,7 @@ S3JniApi(sqlite3_progress_handler(),void,1progress_1handler)(
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
s3jni_db_error(ps->pDb, SQLITE_ERROR,
s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching xCallback() on "
"ProgressHandler object.");
}else{
@@ -4906,8 +4897,9 @@ S3JniApi(sqlite3_set_authorizer(),jint,1set_1authorizer)(
")I");
S3JniUnrefLocal(klazz);
S3JniIfThrew {
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
"Error setting up Java parts of authorizer hook.");
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Error setting up Java parts of "
"authorizer hook.");
}else{
rc = sqlite3_set_authorizer(ps->pDb, s3jni_xAuth, ps);
}
@@ -5191,7 +5183,7 @@ S3JniApi(sqlite3_trace_v2(),jint,1trace_1v2)(
S3JniUnrefLocal(klazz);
S3JniIfThrew {
S3JniExceptionClear;
rc = s3jni_db_error(ps->pDb, SQLITE_ERROR,
rc = s3jni_db_error(env, ps->pDb, SQLITE_ERROR,
"Cannot not find matching call() on "
"TracerCallback object.");
}else{
+3 -1
View File
@@ -245,8 +245,10 @@ extern "C" {
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL 12L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_TEMPBUF_SPILL 13L
#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 12L
#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 13L
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF8
#define org_sqlite_jni_capi_CApi_SQLITE_UTF8 1L
#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16LE
+5 -3
View File
@@ -115,8 +115,9 @@ public final class CApi {
JNIEnv is not cached, else returns true, but this information is
primarily for testing of the JNI bindings and is not information
which client-level code can use to make any informed
decisions. Its return type and semantics are not considered
stable and may change at any time.
decisions. The semantics of its return type and value are not
considered stable and may change at any time. i.e. act as if it
returns null.
*/
public static native boolean sqlite3_java_uncache_thread();
@@ -2585,7 +2586,8 @@ public final class CApi {
public static final int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
public static final int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
public static final int SQLITE_DBSTATUS_CACHE_SPILL = 12;
public static final int SQLITE_DBSTATUS_MAX = 12;
public static final int SQLITE_DBSTATUS_TEMPBUF_SPILL = 13;
public static final int SQLITE_DBSTATUS_MAX = 13;
// encodings
public static final int SQLITE_UTF8 = 1;
+3 -1
View File
@@ -815,7 +815,9 @@ public class Tester1 implements Runnable {
};
// Register and use the function...
int rc = sqlite3_create_function(db, "myfunc", -1, SQLITE_UTF8, func);
int rc = sqlite3_create_function(db, "myfunc", -1,
SQLITE_UTF8 | SQLITE_INNOCUOUS,
func);
affirm(0 == rc);
affirm(0 == xFuncAccum.value);
final sqlite3_stmt stmt = prepare(db, "SELECT myfunc(1,2,3)");
@@ -171,6 +171,7 @@ public final class Sqlite implements AutoCloseable {
public static final int DBSTATUS_DEFERRED_FKS = CApi.SQLITE_DBSTATUS_DEFERRED_FKS;
public static final int DBSTATUS_CACHE_USED_SHARED = CApi.SQLITE_DBSTATUS_CACHE_USED_SHARED;
public static final int DBSTATUS_CACHE_SPILL = CApi.SQLITE_DBSTATUS_CACHE_SPILL;
public static final int DBSTATUS_TEMPBUF_SPILL = CApi.SQLITE_DBSTATUS_TEMPBUF_SPILL;
// Limits
public static final int LIMIT_LENGTH = CApi.SQLITE_LIMIT_LENGTH;
-8
View File
@@ -1122,11 +1122,3 @@ int sqlite3_fileio_init(
}
return rc;
}
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
/* To allow a standalone DLL, make test_windirent.c use the same
* redefined SQLite API calls as the above extension code does.
* Just pull in this .c to accomplish this. As a beneficial side
* effect, this extension becomes a single translation unit. */
# include "test_windirent.c"
#endif
-10
View File
@@ -1,10 +0,0 @@
_fiddle_db_arg
_fiddle_db_filename
_fiddle_exec
_fiddle_experiment
_fiddle_interrupt
_fiddle_main
_fiddle_reset_db
_fiddle_db_handle
_fiddle_db_vfs
_fiddle_export_db
+197 -142
View File
@@ -1,5 +1,6 @@
#######################################################################
# This GNU makefile creates the canonical sqlite3 WASM builds.
#
# This GNU makefile creates the canonical sqlite3 WASM builds. Plus some
# others.
#
# This build assumes a Linux platform and is not intended for
# general-purpose client-level use, except for creating builds with
@@ -10,28 +11,33 @@
#
# default, all = build in dev mode
#
# o0, o1, o2, o3, os, oz = full clean/rebuild with the -Ox level indicated
# by the target name. Rebuild is necessary for all components to get
# the desired optimization level.
# o0, o1, o2, o3, os, oz = full clean/rebuild with the -Ox level
# indicated by the target name. A clean rebuild is necessary for
# all components to get the desired optimization level.
#
# dist = create end user deliverables. Add dist.build=oX to build
# with a specific optimization level, where oX is one of the
# above-listed o? or qo? target names.
# with a specific optimization level, where oX is one of the
# above-listed o? target names.
#
# snapshot = like dist, but uses a zip file name which clearly
# marks it as a prerelease/snapshot build.
# marks it as a prerelease/snapshot build.
#
# clean = clean up
#
# Required tools beyond those needed for the canonical builds:
#
# - Emscripten SDK: https://emscripten.org/docs/getting_started/downloads.html
#
# - The bash shell
#
# - GNU make, GNU sed, GNU awk, GNU grep (all in the $PATH and without
# a "g" prefix like they have on some non-GNU systems)
# - wasm-strip for release builds: https://github.com/WebAssembly/wabt
#
# - wasm-strip for release builds: https://github.com/WebAssembly/wabt.
# It will build without this but the .wasm files will be huge.
#
# - InfoZip for 'dist' zip file
########################################################################
#
default: all
MAKEFILE = $(lastword $(MAKEFILE_LIST))
CLEAN_FILES =
@@ -213,9 +219,8 @@ b.cp = $(call b.mkdir@); \
# $4 = optional $(bin.c-pp) flags
define b.c-pp.shcmd
$(call b.mkdir@); \
$(call b.echo,$(1),$(emo.disk)$(emo.lock) $(bin.c-pp) $(4) $(if $(loud.if),$(2))); \
rm -f $(3); \
$(bin.c-pp) -o $(3) $(4) $(2) || exit; \
$(call b.echo,$(1),$(emo.disk)$(emo.lock)[$(3)] $(4)); \
rm -f $(3); $(bin.c-pp) -o $(3) $(4) $(2) || exit; \
chmod -w $(3)
endef
@@ -227,10 +232,38 @@ endef
# Args: as for $(b.c-pp.shcmd).
define b.c-pp.target
$(3): $$(MAKEFILE_LIST) $$(bin.c-pp) $(2)
@$$(call b.c-pp.shcmd,$(1),$(2),$(3),$(4) $(b.c-pp.target.flags))
@$$(call b.mkdir@)
@$$(call b.c-pp.shcmd,$(1),$(2),$(3),$(4) $$(b.c-pp.target.flags))
CLEAN_FILES += $(3)
endef
#
# The various -D... values used by *.c-pp.js include:
#
# -Dtarget:es6-module: for all ESM module builds
#
# -Dtarget:node: for node.js builds
#
# -Dtarget:es6-module -Dtarget:es6-bundler-friendly: intended for
# "bundler-friendly" ESM module build. These have some restrictions
# on how URL() objects are constructed in some contexts: URLs which
# refer to files which are part of this project must be referenced
# as string literals so that bundlers' static-analysis tools can
# find those files and include them in their bundles.
#
# -Dtarget:es6-module -Dtarget:node: is intended for use by node.js
# for node.js, as opposed to by node.js on behalf of a
# browser. Mixing -sENVIRONMENT=web and -sENVIRONMENT=node leads to
# ambiguity and confusion on node's part, as it's unable to
# reliably determine whether the target is a browser or node.
#
# To repeat: all node.js builds are 100% untested and unsupported.
#
# Most c-pp.D.X are set via $(bin.mkwb) and X is a build name.
# Those make rules reference c-pp.D.64bit, so it should be defined in
# advance.
#
c-pp.D.64bit = -Dbits64
#
@@ -248,11 +281,21 @@ c-pp.D.64bit = -Dbits64
#
# This is intended to be used in makefile targets which generate an
# Emscripten module and where $@ is the module's .js/.mjs file.
#
# This is inherently fragile and has been broken by Emscripten updates
# before.
#
ifeq (1,1)
define b.strip-js-emcc-bindings
echo "$(1) $(emo.garbage) Stripping export wrappers."; \
sed -i -e '/var _sqlite3.*makeInvalidEarly.*;/d' \
-e '/assert.*sqlite3.*missing.*;/d' \
-e '/_sqlite.*createExportWrapper.*;/d' $@
endef
else
b.strip-js-emcc-bindings = \
sed -i -e '/^.*= \(_sqlite3\|_fiddle\)[^=]*=.*createExportWrapper/d' \
-e '/^var \(_sqlite3\|_fiddle\)[^=]*=.*makeInvalidEarlyAccess/d' $@ || exit; \
echo '$(1) $(emo.garbage) (Probably) /createExportWrapper()/d and /makeInvalidEarlyAccess()/d'
echo '$(1) $(emo.bug) (disabled because it breaks emsdk 4.0.16+)'
endif
#
# Set up sqlite3.c and sqlite3.h...
@@ -271,6 +314,7 @@ b.strip-js-emcc-bindings = \
# $(sqlite3.canonical.c) must point to the sqlite3.c in
# the sqlite3 canonical source tree, as that source file
# is required for certain utility and test code.
#
sqlite3.canonical.c = $(dir.top)/sqlite3.c
sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c))
sqlite3.h = $(dir $(sqlite3.c))/sqlite3.h
@@ -280,24 +324,26 @@ sqlite3.h = $(dir $(sqlite3.c))/sqlite3.h
# embedding in the JS files and in building the distribution zip file.
# It must NOT be in $(dir.tmp) because we need it to survive the
# cleanup process for the dist build to work properly.
#
bin.version-info = ./version-info
$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
$(CC) -o $@ -I$(dir $(sqlite3.h)) $(dir.tool)/version-info.c
t-version-info: $(bin.version-info)
DISTCLEAN_FILES += $(bin.version-info)
#
# bin.stripcomments is used for stripping C/C++-style comments from JS
# files. The JS files contain large chunks of documentation which we
# don't need for all builds. That app's -k flag is of particular
# importance here, as it allows us to retain the opening comment
# block(s), which contain the license header and version info.
#
bin.stripccomments = $(dir.tool)/stripccomments
$(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
$(CC) -o $@ $<
t-stripccomments: $(bin.stripccomments)
DISTCLEAN_FILES += $(bin.stripccomments)
ifeq (1,$(MAKING_CLEAN))
SQLITE_C_IS_SEE = 0
else
@@ -325,7 +371,7 @@ endif
# undefine barebones # relatively new gmake feature, not ubiquitous
#
# It's important that sqlite3.h be built to completion before any
# It's important that sqlite3.[ch] be built to completion before any
# other parts of the build run, thus we use .NOTPARALLEL to disable
# parallel build of that file and its dependants. However, that makes
# the whole build non-parallelizable because everything has a dep on
@@ -342,8 +388,10 @@ $(sqlite3.h):
# $(MAKE) -C $(dir.top) sqlite3.c
$(sqlite3.c): $(sqlite3.h)
#
# Common options for building sqlite3-wasm.c and speedtest1.c.
# Explicit ENABLEs...
#
SQLITE_OPT.common = \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_TEMP_STORE=2 \
@@ -360,11 +408,15 @@ SQLITE_OPT.common = \
# removing them from this list will serve only to break the speedtest1
# builds.
#
# Currently always needed but TODO is paring tester1.c-pp.js down
# to be able to run without this:
#
SQLITE_OPT.common += -DSQLITE_WASM_ENABLE_C_TESTS
#
# Extra flags for full-featured builds...
#
SQLITE_OPT.full-featured = \
-DSQLITE_ENABLE_BYTECODE_VTAB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
@@ -421,13 +473,14 @@ else
# -DSQLITE_OMIT_WINDOWFUNC
endif
#
#SQLITE_OPT += -DSQLITE_DEBUG
# Enabling SQLITE_DEBUG will break sqlite3_wasm_vfs_create_file()
# (and thus sqlite3_js_vfs_create_file()). Those functions are
# deprecated and alternatives are in place, but this crash behavior
# can be used to find errant uses of sqlite3_js_vfs_create_file()
# in client code.
########################################################################
#
# The following flags are hard-coded into sqlite3-wasm.c and cannot be
# modified via the build process:
#
@@ -436,10 +489,9 @@ endif
# SQLITE_OMIT_DEPRECATED
# SQLITE_OMIT_UTF16
# SQLITE_OMIT_SHARED_CACHE
########################################################################
#
########################################################################
#
# Adding custom C code via sqlite3_wasm_extra_init.c:
#
# If the canonical build process finds the file
@@ -460,7 +512,7 @@ endif
# make sqlite3_wasm_extra_init.c=my_custom_stuff.c
#
# See example_extra_init.c for an example implementation.
########################################################################
#
sqlite3_wasm_extra_init.c ?= $(wildcard sqlite3_wasm_extra_init.c)
cflags.wasm_extra_init =
ifneq (,$(sqlite3_wasm_extra_init.c))
@@ -481,7 +533,7 @@ endif
#
WASM_CUSTOM_INSTANTIATE = 1
########################################################################
#
# $(bin.c-pp): a minimal text file preprocessor. Like C's but much
# less so.
#
@@ -512,6 +564,7 @@ WASM_CUSTOM_INSTANTIATE = 1
#
# -D... flags which should be included in all invocations should be
# appended to $(b.c-pp.target.flags).
#
bin.c-pp = ./c-pp-lite
$(bin.c-pp): c-pp-lite.c $(sqlite3.c) $(MAKEFILE)
$(CC) -O0 -o $@ c-pp-lite.c $(sqlite3.c) '-DCMPP_DEFAULT_DELIM="//#"' -I$(dir.top) \
@@ -523,7 +576,12 @@ b.c-pp.target.flags ?=
ifeq (1,$(SQLITE_C_IS_SEE))
b.c-pp.target.flags += -Denable-see
endif
api.oo1 ?= 1
ifeq (0,$(api.oo1))
b.c-pp.target.flags += -Domit-oo1
endif
#
# cflags.common = C compiler flags for all builds
cflags.common = -I. -I$(dir $(sqlite3.c)) -std=c99 -fPIC
# emcc.WASM_BIGINT = 1 for BigInt (C int64) support, else 0. The API
@@ -531,13 +589,14 @@ cflags.common = -I. -I$(dir $(sqlite3.c)) -std=c99 -fPIC
# _are not tested_ on any regular basis.
emcc.WASM_BIGINT ?= 1
emcc.MEMORY64 ?= 0
########################################################################
#
# https://emscripten.org/docs/tools_reference/settings_reference.html#memory64
#
# 64-bit build requires wasm-strip 1.0.36 (maybe 1.0.35, but not
# 1.0.34) or will fail to strip with "tables may not be 64-bit".
########################################################################
#
#
# emcc_opt = optimization-related flags. These are primarily used by
# the various oX targets. build times for -O levels higher than 0 are
# painful at dev-time.
@@ -549,14 +608,17 @@ emcc.MEMORY64 ?= 0
# -O2 (which consistently creates the fastest-running deliverables).
# Build time suffers greatly compared to -O0, which is why -O0 is the
# default.
#
ifeq (,$(filter $(OPTIMIZED_TARGETS),$(MAKECMDGOALS)))
emcc_opt ?= -O0
else
emcc_opt ?= -Oz
endif
#
# When passing emcc_opt from the CLI, += and re-assignment have no
# effect, so emcc_opt+=-g3 doesn't work. So...
#
emcc_opt_full = $(emcc_opt) -g3
# ^^^ ALWAYS use -g3. See below for why.
#
@@ -583,26 +645,26 @@ emcc_opt_full = $(emcc_opt) -g3
# Much practice has demonstrated that -O2 consistently gives the best
# runtime speeds, but not by a large enough factor to rule out use of
# -Oz when smaller deliverable size is a priority.
########################################################################
#
########################################################################
#
# EXPORTED_FUNCTIONS.* = files for use with Emscripten's
# -sEXPORTED_FUNCTION flag.
EXPORTED_FUNCTIONS.api.core = $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core
EXPORTED_FUNCTIONS.api.in = $(EXPORTED_FUNCTIONS.api.core)
ifeq (1,$(SQLITE_C_IS_SEE))
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see
endif
ifeq (0,$(wasm-bare-bones))
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
endif
#
EXPORTED_FUNCTIONS.api.in = $(dir.api)/EXPORTED_FUNCTIONS.c-pp
EXPORTED_FUNCTIONS.api = $(dir.tmp)/EXPORTED_FUNCTIONS.api
$(EXPORTED_FUNCTIONS.api): $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE)
@$(call b.mkdir@)
cat $(EXPORTED_FUNCTIONS.api.in) > $@
EXPORTED_FUNCTIONS.c-pp.flags =
ifeq (1,$(wasm-bare-bones))
EXPORTED_FUNCTIONS.c-pp.flags += -Dbare-bones
endif
$(eval $(call b.c-pp.target,filter,\
$(EXPORTED_FUNCTIONS.api.in),\
$(EXPORTED_FUNCTIONS.api),\
$(EXPORTED_FUNCTIONS.c-pp.flags)))
########################################################################
#
# emcc flags for .c/.o/.wasm/.js.
#
emcc.flags =
ifeq (1,$(emcc.verbose))
emcc.flags += -v
@@ -690,9 +752,9 @@ ifeq (,$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY)))
$(error emcc.INITIAL_MEMORY must be one of: 4, 8, 16, 32, 64, 96, 128 (megabytes))
endif
emcc.jsflags += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))
#
# /INITIAL_MEMORY
########################################################################
#emcc.jsflags += -sMEMORY64=$(emcc.MEMORY64)
#
emcc.jsflags += $(emcc.environment)
emcc.jsflags += -sSTACK_SIZE=512KB
@@ -701,7 +763,8 @@ emcc.jsflags += -sSTACK_SIZE=512KB
# VFS, which requires twice that for its xRead() and xWrite() methods.
# 2023-03: those methods have since been adapted to use a malloc()'d
# buffer.
########################################################################
#
# $(sqlite3.js.init-func) is the name Emscripten assigns our exported
# module init/load function. This symbol name is hard-coded in
# $(extern-post-js.js) as well as in numerous docs.
@@ -741,7 +804,7 @@ emcc.jsflags += -sLLD_REPORT_UNDEFINED
#emcc.jsflags += --experimental-pic --unresolved-symbols=ingore-all --import-undefined
#emcc.jsflags += --unresolved-symbols=ignore-all
########################################################################
#
# -sSINGLE_FILE:
# https://github.com/emscripten-core/emscripten/blob/main/src/settings.js
#
@@ -750,12 +813,7 @@ emcc.jsflags += -sLLD_REPORT_UNDEFINED
# cannot wasm-strip the binary before it gets encoded into the JS
# file. The result is that the generated JS file is, because of the
# -g3 debugging info, _huge_.
########################################################################
sqlite3.wasm = $(dir.dout)/sqlite3.wasm
sqlite3-wasm.c = $(dir.api)/sqlite3-wasm.c
sqlite3-wasm.c.in = $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
#
#
# b.call.patch-export-default is used by mkwasmbuilds.c and the
@@ -798,51 +856,6 @@ if [ x1 = x$(1) ]; then \
fi
endef
#
# The various -D... values used by *.c-pp.js include:
#
# -Dtarget:es6-module: for all ESM module builds
#
# -Dtarget:node: for node.js builds
#
# -Dtarget:es6-module -Dtarget:es6-bundler-friendly: intended for
# "bundler-friendly" ESM module build. These have some restrictions
# on how URL() objects are constructed in some contexts: URLs which
# refer to files which are part of this project must be referenced
# as string literals so that bundlers' static-analysis tools can
# find those files and include them in their bundles.
#
# -Dtarget:es6-module -Dtarget:node: is intended for use by node.js
# for node.js, as opposed to by node.js on behalf of a
# browser. Mixing -sENVIRONMENT=web and -sENVIRONMENT=node leads to
# ambiguity and confusion on node's part, as it's unable to
# reliably determine whether the target is a browser or node.
#
# To repeat: all node.js builds are 100% untested and unsupported.
#
########################################################################
#
# Inputs/outputs for the sqlite3-api.js family.
#
# sqlite3-api.jses = the list of JS files which make up
# sqlite3-api.js, in the order they need to be assembled.
sqlite3-api.jses = $(sqlite3-license-version.js)
sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js
sqlite3-api.jses += $(dir.common)/whwasmutil.js
sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js
sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.c-pp.js
sqlite3-api.jses += $(sqlite3-api-build-version.js)
sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js
ifeq (0,$(wasm-bare-bones))
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
endif
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
#
# $(sqlite3-license-version.js) contains the license header and
# in-comment build version info.
@@ -852,9 +865,8 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
#
sqlite3-license-version.js = $(dir.tmp)/sqlite3-license-version.js
$(sqlite3-license-version.js): $(bin.version-info) \
$(dir.api)/sqlite3-license-version-header.js
@echo '$(logtag.@) $(emo.disk)'; { \
$(call b.mkdir@); \
$(dir.api)/sqlite3-license-version-header.js $(MAKEFILE)
@$(call b.mkdir@); echo '$(logtag.@) $(emo.disk)'; { \
cat $(dir.api)/sqlite3-license-version-header.js || exit $$?; \
echo '/*'; \
echo '** This code was built from sqlite3 version...'; \
@@ -862,7 +874,7 @@ $(sqlite3-license-version.js): $(bin.version-info) \
awk '/define SQLITE_VERSION/{$$1=""; print "**" $$0}' $(sqlite3.h); \
awk '/define SQLITE_SOURCE_ID/{$$1=""; print "**" $$0}' $(sqlite3.h); \
echo '**'; echo '** Emscripten SDK: $(emcc.version)'; \
echo '**'; \
echo '**'; echo '** Preprocessed by:'; echo '** @c-pp::ARGV@'; \
echo '*/'; \
} > $@
@@ -881,6 +893,33 @@ $(sqlite3-api-build-version.js): $(bin.version-info) $(MAKEFILE)
echo '});'; \
} > $@
#
# Inputs/outputs for the sqlite3-api.js family.
#
# sqlite3-api.jses = the list of JS files which make up
# sqlite3-api.js, in the order they need to be assembled.
sqlite3-api.jses = $(sqlite3-license-version.js)
sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js
sqlite3-api.jses += $(sqlite3-api-build-version.js)
sqlite3-api.jses += $(dir.common)/whwasmutil.js
sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js
sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js
ifeq (0,$(wasm-bare-bones))
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
endif
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js
# Parallel builds can fail if $(sqlite3-license-version.js) is not
# created early enough, so make all files in $(sqlite-api.jses) except
# for $(sqlite3-license-version.js) depend on
# $(sqlite3-license-version.js).
deps.jses = $(filter-out $(sqlite3-license-version.js),$(sqlite3-api.jses))
$(deps.jses): $(sqlite3-license-version.js)
#
# extern-post-js* and extern-pre-js* are files for use with
# Emscripten's --extern-pre-js and --extern-post-js flags.
@@ -918,7 +957,7 @@ $(post-js.in.js): $(MKDIR.bld) $(post-jses.js) $(MAKEFILE)
done > $@
#
# speedtest1 decls needed before the $(bin.mkws)-generated makefile
# speedtest1 decls needed before the $(bin.mkwb)-generated makefile
# is included.
#
bin.speedtest1 = ../../speedtest1
@@ -958,9 +997,10 @@ endif
########################################################################
EXPORTED_FUNCTIONS.fiddle = $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle
$(EXPORTED_FUNCTIONS.fiddle): $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE_LIST)
@$(b.mkdir@)
@sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@
$(EXPORTED_FUNCTIONS.fiddle): $(EXPORTED_FUNCTIONS.api.in) $(MAKEFILE_LIST)
@$(call b.mkdir@)
@$(call b.c-pp.shcmd,filter,$(EXPORTED_FUNCTIONS.api.in),\
$@,$(EXPORTED_FUNCTIONS.c-pp.flags) -Dfiddle)
@echo $(logtag.@) $(emo.disk)
emcc.flags.fiddle = \
@@ -993,7 +1033,7 @@ clean-fiddle:
$(dir.fiddle)/*.wasm \
$(dir.fiddle)/sqlite3-opfs-*.js \
$(dir.fiddle)/*.gz \
EXPORTED_FUNCTIONS.fiddle
$(EXPORTED_FUNCTIONS.fiddle)
rm -fr $(dir.fiddle-debug)
emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
@@ -1001,11 +1041,6 @@ emcc.flags.fiddle.debug = $(emcc.flags.fiddle) \
-DSQLITE_ENABLE_SELECTTRACE \
-DSQLITE_ENABLE_WHERETRACE
fiddle.EXPORTED_FUNCTIONS.in = \
EXPORTED_FUNCTIONS.fiddle.in \
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core \
$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
fiddle.c.in = $(dir.top)/shell.c $(sqlite3-wasm.c)
#
@@ -1028,6 +1063,14 @@ cflags.wasmfs = -DSQLITE_ENABLE_WASMFS
# end wasmfs (the rest is in mkwasmbuilds.c)
#
#
#
#
sqlite3-wasm.c = $(dir.api)/sqlite3-wasm.c
# List of input files for compiling $(sqlite3-wasm.c). That file
# #include's sqlite3.c directly, so it's implicitly includes here.
sqlite3-wasm.c.in = $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
#
# $(bin.mkwb) is used for generating much of the makefile code for the
# various wasm builds. It used to be generated in this makefile via a
@@ -1083,10 +1126,10 @@ sqlite3.ext.js =
define gen-worker1
# $1 = X.ext part of sqlite3-worker1X.ext
# $2 = $(c-pp.D.NAME)
$(call b.c-pp.target,filter,$(dir.api)/sqlite3-worker1.c-pp.js,\
$(dir.dout)/sqlite3-worker1$(1),$(2))
sqlite3.ext.js += $(dir.dout)/sqlite3-worker1$(1)
all: $(dir.dout)/sqlite3-worker1$(1)
$(call b.c-pp.target,filter,$$(dir.api)/sqlite3-worker1.c-pp.js,\
$$(dir.dout)/sqlite3-worker1$(1),$(2))
sqlite3.ext.js += $$(dir.dout)/sqlite3-worker1$(1)
all: $$(dir.dout)/sqlite3-worker1$(1)
endef
$(eval $(call gen-worker1,.js,$(c-pp.D.vanilla)))
@@ -1100,10 +1143,10 @@ $(eval $(call gen-worker1,-bundler-friendly.mjs,$(c-pp.D.bundler)))
define gen-promiser
# $1 = X.ext part of sqlite3-worker1-promiserX.ext
# $2 = $(c-pp.D.NAME)
$(call b.c-pp.target,filter,$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\
$(dir.dout)/sqlite3-worker1-promiser$(1),$(2))
sqlite3.ext.js += $(dir.dout)/sqlite3-worker1-promiser$(1)
all: $(dir.dout)/sqlite3-worker1-promiser$(1)
$(call b.c-pp.target,filter,$$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\
$$(dir.dout)/sqlite3-worker1-promiser$(1),$(2))
sqlite3.ext.js += $$(dir.dout)/sqlite3-worker1-promiser$(1)
all: $$(dir.dout)/sqlite3-worker1-promiser$(1)
endef
$(eval $(call gen-promiser,.js,$(c-pp.D.vanilla)))
@@ -1145,12 +1188,19 @@ $(dir.dout)/sqlite3-opfs-async-proxy.js: $(dir.api)/sqlite3-opfs-async-proxy.js
# we don't otherwise have a great place to attach them such that
# they're always copied when we need them.
#
# The var $(out.$(B).js) comes from $(bin.mkwb) and $(B) is the name
# of a build set up by that tool, e.g. b-vanilla or b-esm64.
#
$(foreach B,$(b.names),$(eval $(out.$(B).js): $(sqlite3.ext.js)))
#
# b-all: builds all available js/wasm builds.
#
$(foreach B,$(b.names),$(eval b-all: $(out.$(B).js)))
#$(foreach B,$(b.names),$(eval pre: $(pre-js.$(B).js)))
$(foreach B,$(b.names),$(eval post: $(post-js.$(B).js)))
#
# speedtest1 is our primary benchmarking tool.
#
@@ -1199,10 +1249,9 @@ speedtest1.exit-runtime1 = -sEXIT_RUNTIME=1
# -sEXIT_RUNTIME=1 but we need EXIT_RUNTIME=0 for the worker-based app
# which runs speedtest1 multiple times.
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.core)
@$(call b.echo,@,$(emo.disk)); \
$(call b.mkdir@); \
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ || exit
$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api)
@$(call b.mkdir@); $(call b.echo,@,$(emo.disk)); \
{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api); } > $@ || exit
speedtest1: b-speedtest1
#
@@ -1244,9 +1293,11 @@ $(eval $(call gen-st64,speedtest1-worker.js,speedtest1-worker-64bit.js,speedtest
#
# To create those, we filter tester1.c-pp.js/html with $(bin.c-pp)...
#
# tester1.js variants:
#
define gen-tester1.js
# $1 = build name to have dep on
# $1 = build name to have a dep on
# $2 = suffix for tester1SUFFIX JS
# $3 = $(bin.c-pp) flags
$(call b.c-pp.target,test,tester1.c-pp.js,tester1$(2),$(3))
@@ -1255,20 +1306,18 @@ tester1-$(1): tester1$(2)
tester1: tester1$(2)
endef
$(eval $(call gen-tester1.js,vanilla,.js, \
$(c-pp.D.vanilla) \
-Dsqlite3.js=$(dir.dout)/sqlite3.js))
$(eval $(call gen-tester1.js,vanilla64,-64bit.js, \
$(c-pp.D.vanilla64) \
-Dsqlite3.js=$(dir.dout)/sqlite3-64bit.js))
$(eval $(call gen-tester1.js,esm,.mjs, \
$(c-pp.D.esm) \
-Dsqlite3.js=$(dir.dout)/sqlite3.mjs))
$(eval $(call gen-tester1.js,esm64,-64bit.mjs, \
$(c-pp.D.esm64) \
-Dsqlite3.js=$(dir.dout)/sqlite3-64bit.mjs))
$(eval $(call gen-tester1.js,vanilla,.js,\
$(c-pp.D.vanilla) -Dsqlite3.js=$(dir.dout)/sqlite3.js))
$(eval $(call gen-tester1.js,vanilla64,-64bit.js,\
$(c-pp.D.vanilla64) -Dsqlite3.js=$(dir.dout)/sqlite3-64bit.js))
$(eval $(call gen-tester1.js,esm,.mjs,\
$(c-pp.D.esm) -Dsqlite3.js=$(dir.dout)/sqlite3.mjs))
$(eval $(call gen-tester1.js,esm64,-64bit.mjs,\
$(c-pp.D.esm64) -Dsqlite3.js=$(dir.dout)/sqlite3-64bit.mjs))
#
# tester1.html variants:
#
define gen-tester1.html
# $1 = build name to have a dep on
# $2 = filename suffix: empty, -64bit, -esm, esm-64bit
@@ -1303,9 +1352,11 @@ $(eval $(call gen-tester1.html,esm64,-esm-64bit,\
-Dtester1.js=tester1-64bit.mjs \
-Dsqlite3.js=$(dir.dout)/sqlite3-64bit.mjs))
# tester1-worker.html variants:
# There is no ESM variant of this file. Instead, that page accepts a
# ?esm URL flag to switch to ESM mode.
#
# tester1-worker.html variants: There is no ESM variant of this
# file. Instead, that page accepts the ?esm URL flag to switch to ESM
# mode.
#
$(eval $(call b.c-pp.target,test,tester1-worker.c-pp.html,\
tester1-worker.html,-Dbitness=32))
$(eval $(call b.c-pp.target,test,tester1-worker.c-pp.html,\
@@ -1315,8 +1366,9 @@ tester1-worker.html: tester1.mjs
tester1-worker-64bit.html: tester1-64bit.mjs
all: tester1
#
# end tester1
########################################################################
#
#
# Convenience rules to rebuild with various -Ox levels. Much
@@ -1327,6 +1379,7 @@ all: tester1
#
# Achtung: build times with anything higher than -O0 are somewhat
# painful, which is why -O0 is the default.
#
.PHONY: o0 o1 o2 o3 os oz
emcc-opt-extra =
#ifeq (1,$(wasm-bare-bones))
@@ -1377,7 +1430,9 @@ push-testing:
ssh wasm-testing 'cd $(wasm-testing.dir) && bash .gzip' || \
echo "SSH failed: it's likely that stale content will be served via old gzip files."
#
# build everything needed by push-testing with -Oz
#
.PHONY: for-testing
for-testing: emcc_opt=-Oz
for-testing: loud=1
@@ -1462,9 +1517,9 @@ endif
dist-name-prefix = sqlite-wasm$(dist-name-extra)
.PHONY: dist
dist:
./mkdist.sh $(dist-name-prefix)
$(bin.bash) ./mkdist.sh $(dist-name-prefix)
snapshot:
./mkdist.sh $(dist-name-prefix) --snapshot
$(bin.bash) ./mkdist.sh $(dist-name-prefix) --snapshot
endif
# ^^^ making dist/snapshot
CLEAN_FILES += $(wildcard sqlite-wasm-*.zip)
@@ -155,3 +155,92 @@ _sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value
//#if not bare-bones
_sqlite3_column_database_name
_sqlite3_column_origin_name
_sqlite3_column_table_name
_sqlite3_create_module
_sqlite3_create_module_v2
_sqlite3_create_window_function
_sqlite3_declare_vtab
_sqlite3_drop_modules
_sqlite3_preupdate_blobwrite
_sqlite3_preupdate_count
_sqlite3_preupdate_depth
_sqlite3_preupdate_hook
_sqlite3_preupdate_new
_sqlite3_preupdate_old
_sqlite3_progress_handler
_sqlite3_set_authorizer
_sqlite3_vtab_collation
_sqlite3_vtab_distinct
_sqlite3_vtab_in
_sqlite3_vtab_in_first
_sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value
_sqlite3changegroup_add
_sqlite3changegroup_add_strm
_sqlite3changegroup_delete
_sqlite3changegroup_new
_sqlite3changegroup_output
_sqlite3changegroup_output_strm
_sqlite3changeset_apply
_sqlite3changeset_apply_strm
_sqlite3changeset_apply_v2
_sqlite3changeset_apply_v2_strm
_sqlite3changeset_apply_v3
_sqlite3changeset_apply_v3_strm
_sqlite3changeset_concat
_sqlite3changeset_concat_strm
_sqlite3changeset_conflict
_sqlite3changeset_finalize
_sqlite3changeset_fk_conflicts
_sqlite3changeset_invert
_sqlite3changeset_invert_strm
_sqlite3changeset_new
_sqlite3changeset_next
_sqlite3changeset_old
_sqlite3changeset_op
_sqlite3changeset_pk
_sqlite3changeset_start
_sqlite3changeset_start_strm
_sqlite3changeset_start_v2
_sqlite3changeset_start_v2_strm
_sqlite3session_attach
_sqlite3session_changeset
_sqlite3session_changeset_size
_sqlite3session_changeset_strm
_sqlite3session_config
_sqlite3session_create
_sqlite3session_delete
_sqlite3session_diff
_sqlite3session_enable
_sqlite3session_indirect
_sqlite3session_isempty
_sqlite3session_memory_used
_sqlite3session_object_config
_sqlite3session_patchset
_sqlite3session_patchset_strm
_sqlite3session_table_filter
//#endif not bare-bones
//#if enable-see
_sqlite3_key
_sqlite3_key_v2
_sqlite3_rekey
_sqlite3_rekey_v2
_sqlite3_activate_see
//#endif enable-see
//#if fiddle
_fiddle_db_arg
_fiddle_db_filename
_fiddle_exec
_fiddle_experiment
_fiddle_interrupt
_fiddle_main
_fiddle_reset_db
_fiddle_db_handle
_fiddle_db_vfs
_fiddle_export_db
//#endif fiddle
@@ -1,68 +0,0 @@
_sqlite3_column_database_name
_sqlite3_column_origin_name
_sqlite3_column_table_name
_sqlite3_create_module
_sqlite3_create_module_v2
_sqlite3_create_window_function
_sqlite3_declare_vtab
_sqlite3_drop_modules
_sqlite3_preupdate_blobwrite
_sqlite3_preupdate_count
_sqlite3_preupdate_depth
_sqlite3_preupdate_hook
_sqlite3_preupdate_new
_sqlite3_preupdate_old
_sqlite3_progress_handler
_sqlite3_set_authorizer
_sqlite3_vtab_collation
_sqlite3_vtab_distinct
_sqlite3_vtab_in
_sqlite3_vtab_in_first
_sqlite3_vtab_in_next
_sqlite3_vtab_nochange
_sqlite3_vtab_on_conflict
_sqlite3_vtab_rhs_value
_sqlite3changegroup_add
_sqlite3changegroup_add_strm
_sqlite3changegroup_delete
_sqlite3changegroup_new
_sqlite3changegroup_output
_sqlite3changegroup_output_strm
_sqlite3changeset_apply
_sqlite3changeset_apply_strm
_sqlite3changeset_apply_v2
_sqlite3changeset_apply_v2_strm
_sqlite3changeset_apply_v3
_sqlite3changeset_apply_v3_strm
_sqlite3changeset_concat
_sqlite3changeset_concat_strm
_sqlite3changeset_conflict
_sqlite3changeset_finalize
_sqlite3changeset_fk_conflicts
_sqlite3changeset_invert
_sqlite3changeset_invert_strm
_sqlite3changeset_new
_sqlite3changeset_next
_sqlite3changeset_old
_sqlite3changeset_op
_sqlite3changeset_pk
_sqlite3changeset_start
_sqlite3changeset_start_strm
_sqlite3changeset_start_v2
_sqlite3changeset_start_v2_strm
_sqlite3session_attach
_sqlite3session_changeset
_sqlite3session_changeset_size
_sqlite3session_changeset_strm
_sqlite3session_config
_sqlite3session_create
_sqlite3session_delete
_sqlite3session_diff
_sqlite3session_enable
_sqlite3session_indirect
_sqlite3session_isempty
_sqlite3session_memory_used
_sqlite3session_object_config
_sqlite3session_patchset
_sqlite3session_patchset_strm
_sqlite3session_table_filter
@@ -1,5 +0,0 @@
_sqlite3_key
_sqlite3_key_v2
_sqlite3_rekey
_sqlite3_rekey_v2
_sqlite3_activate_see
@@ -1,3 +0,0 @@
FS
wasmMemory
+43 -39
View File
@@ -23,7 +23,7 @@ this writing, but is not set in stone forever and may change at any
time. This doc targets maintainers of this code and those wanting to
dive in to the details, not end user.
First off, a pikchr of the proverbial onion:
First off, a [pikchr][] of the proverbial onion:
```pikchr toggle center
scale = 0.85
@@ -60,14 +60,14 @@ maintenance point of view.
At the center of the onion is `sqlite3-api.js`, which gets generated
by concatenating the following files together in their listed order:
- **`sqlite3-api-prologue.js`**\
- **`sqlite3-api-prologue.js`**
Contains the initial bootstrap setup of the sqlite3 API
objects. This is exposed as a function, rather than objects, so that
the next step can pass in a config object which abstracts away parts
of the WASM environment, to facilitate plugging it in to arbitrary
WASM toolchains. The bootstrapping function gets removed from the
global scope in a later stage of the bootstrapping process.
- **`../common/whwasmutil.js`**\
- **`../common/whwasmutil.js`**
A semi-third-party collection of JS/WASM utility code intended to
replace much of the Emscripten glue. The sqlite3 APIs internally use
these APIs instead of their Emscripten counterparts, in order to be
@@ -77,79 +77,78 @@ by concatenating the following files together in their listed order:
toolchains. It is "semi-third-party" in that it was created in order
to support this tree but is standalone and maintained together
with...
- **`../jaccwabyt/jaccwabyt.js`**\
- **`../jaccwabyt/jaccwabyt.js`**
Another semi-third-party API which creates bindings between JS
and C structs, such that changes to the struct state from either JS
or C are visible to the other end of the connection. This is also an
independent spinoff project, conceived for the sqlite3 project but
maintained separately.
- **`sqlite3-api-glue.js`**\
- **`sqlite3-api-glue.js`**
Invokes functionality exposed by the previous two files to flesh out
low-level parts of `sqlite3-api-prologue.js`. Most of these pieces
involve populating the `sqlite3.capi.wasm` object and creating
`sqlite3.capi.sqlite3_...()` bindings. This file also deletes most
global-scope symbols the above files create, effectively moving them
into the scope being used for initializing the API.
- **`<build>/sqlite3-api-build-version.js`**\
- **`<build>/sqlite3-api-build-version.js`**
Gets created by the build process and populates the
`sqlite3.version` object. This part is not critical, but records the
version of the library against which this module was built.
- **`sqlite3-api-oo1.js`**\
- **`sqlite3-api-oo1.js`**
Provides a high-level object-oriented wrapper to the lower-level C
API, colloquially known as OO API #1. Its API is similar to other
high-level sqlite3 JS wrappers and should feel relatively familiar
to anyone familiar with such APIs. It is not a "required component"
and can be elided from builds which do not want it.
- **`sqlite3-api-worker1.js`**\
- **`sqlite3-api-worker1.js`**
A Worker-thread-based API which uses OO API #1 to provide an
interface to a database which can be driven from the main Window
thread via the Worker message-passing interface. Like OO API #1,
this is an optional component, offering one of any number of
potential implementations for such an API.
- **`sqlite3-worker1.js`**\
- **`sqlite3-worker1.js`**
Is not part of the amalgamated sources and is intended to be
loaded by a client Worker thread. It loads the sqlite3 module
and runs the Worker #1 API which is implemented in
`sqlite3-api-worker1.js`.
- **`sqlite3-worker1-promiser.js`**\
- **`sqlite3-worker1-promiser.js`**
Is likewise not part of the amalgamated sources and provides
a Promise-based interface into the Worker #1 API. This is
a far user-friendlier way to interface with databases running
in a Worker thread.
- **`sqlite3-vfs-helper.js`**\
- **`sqlite3-vfs-helper.js`**
Installs the `sqlite3.vfs` namespace, which contain helpers for use
by downstream code which creates `sqlite3_vfs` implementations.
- **`sqlite3-vtab-helper.js`**\
- **`sqlite3-vtab-helper.js`**
Installs the `sqlite3.vtab` namespace, which contain helpers for use
by downstream code which creates `sqlite3_module` implementations.
- **`sqlite3-vfs-opfs.c-pp.js`**\
- **`sqlite3-vfs-opfs.c-pp.js`**
is an sqlite3 VFS implementation which supports the [Origin-Private
FileSystem (OPFS)][OPFS] as a storage layer to provide persistent
storage for database files in a browser. It requires...
- **`sqlite3-opfs-async-proxy.js`**\
- **`sqlite3-opfs-async-proxy.js`**
is the asynchronous backend part of the [OPFS][] proxy. It
speaks directly to the (async) OPFS API and channels those
results back to its synchronous counterpart. This file, because
it must be started in its own Worker, is not part of the
amalgamation.
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**\
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**
is another sqlite3 VFS supporting the [OPFS][], but uses a
completely different approach than the above-listed one.
- **`sqlite3-api-cleanup.js`**\
The previous files do not immediately extend the library. Instead
they add callback functions to be called during its
bootstrapping. Some also temporarily create global objects in order
to communicate their state to the files which follow them. This file
cleans up any dangling globals and runs the API bootstrapping
process, which is what finally executes the initialization code
installed by the previous files. As of this writing, this code
ensures that the previous files leave no more than a single global
symbol installed - `sqlite3InitModule()`. When adapting the API for
non-Emscripten toolchains, this "should" be the only file, of those
in this list, where changes are needed. The Emscripten-specific
pieces described below may also require counterparts in any as-yet
hypothetical alternative build.
The previous files do not immediately extend the library. Instead they
install a global function `sqlite3ApiBootstrap()`, which downstream
code must call to configure the library for the current JS/WASM
environment. Each file listed above pushes a callback into the
bootstrapping queue, to be called as part of `sqlite3ApiBootstrap()`.
Some files also temporarily create global objects in order to
communicate their state to the files which follow them. Those
get cleaned up vi `post-js-footer.js`, described below.
Adapting the build for non-Emscripten toolchains essentially requires packaging
the above files, concatated together, into that toolchain's "JS glue"
and, in the final stage of that glue, call `sqlite3ApiBootstrap()` and
return its result to the end user.
**Files with the extension `.c-pp.js`** are intended [to be processed
with `c-pp`](#c-pp), noting that such preprocessing may be applied
@@ -171,23 +170,27 @@ from this file rather than `sqlite3.c`.
The following Emscripten-specific files are injected into the
build-generated `sqlite3.js` along with `sqlite3-api.js`.
- **`extern-pre-js.js`**\
- **`extern-pre-js.js`**
Emscripten-specific header for Emscripten's `--extern-pre-js`
flag. As of this writing, that file is only used for experimentation
purposes and holds no code relevant to the production deliverables.
- **`pre-js.c-pp.js`**\
- **`pre-js.c-pp.js`**
Emscripten-specific header for Emscripten's `--pre-js` flag. This
file overrides certain Emscripten behavior before Emscripten does
most of its work.
- **`post-js-header.js`**\
- **`post-js-header.js`**
Emscripten-specific header for the `--post-js` input. It opens up,
but does not close, a function used for initializing the library.
- (**`sqlite3-api.js`** gets sandwiched between these &uarr; two
&darr; files.)
- **`post-js-footer.js`**\
- **`sqlite3-api.js`** gets sandwiched between these &uarr; two
&darr; files.
- **`post-js-footer.js`**
Emscripten-specific footer for the `--post-js` input. This closes
off the function opened by `post-js-header.js`.
- **`extern-post-js.c-pp.js`**\
off the function opened by `post-js-header.js`. This file cleans up
any dangling globals and runs `sqlite3ApiBootstrap()`. As of this
writing, this code ensures that the previous files leave no more
than a single global symbol installed - `sqlite3InitModule()`.
- **`extern-post-js.c-pp.js`**
Emscripten-specific header for Emscripten's `--extern-post-js`
flag. This file is run in the global scope. It overwrites the
Emscripten-installed `sqlite3InitModule()` function with one which
@@ -205,9 +208,10 @@ Preprocessing of Source Files
Certain files in the build require preprocessing to filter in/out
parts which differ between vanilla JS, ES6 Modules, and node.js
builds. The preprocessor application itself is in
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
of such preprocessing are maintained in
[`c-pp-lite.c`](/file/ext/wasm/c-pp-lite.c) and the complete technical
details of such preprocessing are maintained in
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
[OPFS]: https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system
[pikchr]: https://pikchr.org
+1 -1
View File
@@ -26,7 +26,7 @@ const toExportForESM =
*/
const originalInit = sqlite3InitModule;
if(!originalInit){
throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build.");
throw new Error("Expecting sqlite3InitModule to be defined by the Emscripten build.");
}
/**
We need to add some state which our custom Module.locateFile()
+69
View File
@@ -1,3 +1,72 @@
/*
2022-07-22
The author disclaims copyright to this source code. In place of a
legal notice, here is a blessing:
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
***********************************************************************
This file is the tail end of the sqlite3-api.js constellation,
closing the function scope opened by post-js-header.js.
In terms of amalgamation code placement, this file is appended
immediately after the final sqlite3-api-*.js piece. Those files
cooperate to prepare sqlite3ApiBootstrap() and this file calls it.
It is run within a context which gives it access to Emscripten's
Module object, after sqlite3.wasm is loaded but before
sqlite3ApiBootstrap() has been called.
Because this code resides (after building) inside the function
installed by post-js-header.js, it has access to state set up by
pre-js.c-pp.js and friends.
*/
try{
/* We are in the closing block of Module.runSQLite3PostLoadInit(), so
its arguments are visible here. */
/* Config options for sqlite3ApiBootstrap(). */
const bootstrapConfig = Object.assign(
Object.create(null),
/** The WASM-environment-dependent configuration for sqlite3ApiBootstrap() */
{
memory: ('undefined'!==typeof wasmMemory)
? wasmMemory
: EmscriptenModule['wasmMemory'],
exports: ('undefined'!==typeof wasmExports)
? wasmExports /* emscripten >=3.1.44 */
: (Object.prototype.hasOwnProperty.call(EmscriptenModule,'wasmExports')
? EmscriptenModule['wasmExports']
: EmscriptenModule['asm']/* emscripten <=3.1.43 */)
},
globalThis.sqlite3ApiBootstrap.defaultConfig, // default options
globalThis.sqlite3ApiConfig || {} // optional client-provided options
);
sqlite3InitScriptInfo.debugModule("Bootstrapping lib config", bootstrapConfig);
/**
For purposes of the Emscripten build, call sqlite3ApiBootstrap().
Ideally clients should be able to inject their own config here,
but that's not practical in this particular build constellation
because of the order everything happens in. Clients may either
define globalThis.sqlite3ApiConfig or modify
globalThis.sqlite3ApiBootstrap.defaultConfig to tweak the default
configuration used by a no-args call to sqlite3ApiBootstrap(),
but must have first loaded their WASM module in order to be able
to provide the necessary configuration state.
*/
const p = globalThis.sqlite3ApiBootstrap(bootstrapConfig);
delete globalThis.sqlite3ApiBootstrap;
return p /* the eventual result of globalThis.sqlite3InitModule() */;
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
}
//console.warn("This is the end of the Module.runSQLite3PostLoadInit handler.");
}/*Module.runSQLite3PostLoadInit(...)*/;
//console.warn("This is the end of the setup of the (pending) Module.runSQLite3PostLoadInit");
+4 -6
View File
@@ -3,14 +3,13 @@
post-js.js for use with Emscripten's --post-js flag, so it gets
injected in the earliest stages of sqlite3InitModule().
This function wraps the whole SQLite3 library but does not
bootstrap it.
Running this function will bootstrap the library and return
a Promise to the sqlite3 namespace object.
In the canonical builds, this gets called by extern-post-js.c-pp.js
*/
Module.runSQLite3PostLoadInit = function(
sqlite3InitScriptInfo /* populated by extern-post-js.c-pp.js */,
Module.runSQLite3PostLoadInit = async function(
sqlite3InitScriptInfo,
EmscriptenModule/*the Emscripten-style module object*/,
sqlite3IsUnderTest
){
@@ -35,7 +34,6 @@ Module.runSQLite3PostLoadInit = function(
- sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls
- sqlite3-vfs-opfs.c-pp.js => OPFS VFS
- sqlite3-vfs-opfs-sahpool.c-pp.js => OPFS SAHPool VFS
- sqlite3-api-cleanup.js => final bootstrapping phase
- post-js-footer.js => this file's epilogue
And all of that gets sandwiched between extern-pre-js.js and
+25 -6
View File
@@ -14,12 +14,33 @@
itself. i.e. try to keep file-local symbol names obnoxiously
collision-resistant.
*/
/**
This file was preprocessed using:
//#@policy error
@c-pp::ARGV@
//#@policy off
*/
//#if unsupported-build
/**
UNSUPPORTED BUILD:
This SQLite JS build configuration is entirely unsupported! It has
not been tested beyond the ability to compile it. It may not
load. It may not work properly. Only builds targeting browser
environments are supported and tested.
*/
//#endif
(function(Module){
const sIMS =
globalThis.sqlite3InitModuleState/*from extern-post-js.c-pp.js*/
|| Object.assign(Object.create(null),{
debugModule: ()=>{
console.warn("globalThis.sqlite3InitModuleState is missing");
/* In WASMFS builds this file gets loaded once per thread,
but sqlite3InitModuleState is not getting set for the
worker threads? That those workers seem to function fine
despite that is curious. */
debugModule: function(){
console.warn("globalThis.sqlite3InitModuleState is missing",arguments);
}
});
delete globalThis.sqlite3InitModuleState;
@@ -72,8 +93,7 @@
//#endif target:es6-module
}.bind(sIMS);
//#if Module.instantiateWasm
//#if not wasmfs
//#if Module.instantiateWasm and not wasmfs
/**
Override Module.instantiateWasm().
@@ -109,7 +129,6 @@
.then(finalThen)
return loadWasm();
}.bind(sIMS);
//#endif not wasmfs
//#endif Module.instantiateWasm
//#endif Module.instantiateWasm and not wasmfs
})(Module);
/* END FILE: api/pre-js.js. */
-83
View File
@@ -1,83 +0,0 @@
/*
2022-07-22
The author disclaims copyright to this source code. In place of a
legal notice, here is a blessing:
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
***********************************************************************
This file is the tail end of the sqlite3-api.js constellation,
intended to be appended after all other sqlite3-api-*.js files so
that it can finalize any setup and clean up any global symbols
temporarily used for setting up the API's various subsystems.
In Emscripten builds it's run in the context of what amounts to a
Module.postRun handler, though it's no longer actually a postRun
handler because Emscripten 4.0 changed postRun semantics in an
incompatible way.
In terms of amalgamation code placement, this file is appended
immediately after the final sqlite3-api-*.js piece. Those files
cooperate to prepare sqlite3ApiBootstrap() and this file calls it.
It is run within a context which gives it access to Emscripten's
Module object, after sqlite3.wasm is loaded but before
sqlite3ApiBootstrap() has been called.
Because this code resides (after building) inside the function
installed by post-js-header.js, it has access to the
*/
'use strict';
if( 'undefined' === typeof EmscriptenModule/*from post-js-header.js*/ ){
console.warn("This is not running in the context of Module.runSQLite3PostLoadInit()");
throw new Error("sqlite3-api-cleanup.js expects to be running in the "+
"context of its Emscripten module loader.");
}
try{
/* Config options for sqlite3ApiBootstrap(). */
const bootstrapConfig = Object.assign(
Object.create(null),
globalThis.sqlite3ApiBootstrap.defaultConfig, // default options
globalThis.sqlite3ApiConfig || {}, // optional client-provided options
/** The WASM-environment-dependent configuration for sqlite3ApiBootstrap() */
{
memory: ('undefined'!==typeof wasmMemory)
? wasmMemory
: EmscriptenModule['wasmMemory'],
exports: ('undefined'!==typeof wasmExports)
? wasmExports /* emscripten >=3.1.44 */
: (Object.prototype.hasOwnProperty.call(EmscriptenModule,'wasmExports')
? EmscriptenModule['wasmExports']
: EmscriptenModule['asm']/* emscripten <=3.1.43 */)
}
);
/** Figure out if this is a 32- or 64-bit WASM build. */
bootstrapConfig.wasmPtrIR =
'number'===(typeof bootstrapConfig.exports.sqlite3_libversion())
? 'i32' :'i64';
const sIMS = sqlite3InitScriptInfo;
sIMS.debugModule("Bootstrapping lib config", sIMS);
/**
For purposes of the Emscripten build, call sqlite3ApiBootstrap().
Ideally clients should be able to inject their own config here,
but that's not practical in this particular build constellation
because of the order everything happens in. Clients may either
define globalThis.sqlite3ApiConfig or modify
globalThis.sqlite3ApiBootstrap.defaultConfig to tweak the default
configuration used by a no-args call to sqlite3ApiBootstrap(),
but must have first loaded their WASM module in order to be able
to provide the necessary configuration state.
*/
const p = globalThis.sqlite3ApiBootstrap(bootstrapConfig);
delete globalThis.sqlite3ApiBootstrap;
return p /* the eventual result of globalThis.sqlite3InitModule() */;
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
}
throw new Error("Maintenance required: this line should never be reached");
+47 -1
View File
@@ -120,7 +120,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
//#define proxy-text-apis=1
//#if not proxy-text-apis
/* Search this file for tag:proxy-text-apis to see what this is about. */
["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
//#endif
["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
["sqlite3_commit_hook", "void*", [
@@ -317,7 +321,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_value_numeric_type", "int", "sqlite3_value*"],
["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
["sqlite3_value_subtype", "int", "sqlite3_value*"],
//#if not proxy-text-apis
["sqlite3_value_text", "string", "sqlite3_value*"],
//#endif
["sqlite3_value_type", "int", "sqlite3_value*"],
["sqlite3_vfs_find", "*", "string"],
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
@@ -1654,6 +1660,45 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*sqlite3_bind_text/blob()*/
//#if proxy-text-apis
if(!capi.sqlite3_column_text){
/*[tag:proxy-text-apis]
As discussed at:
https://sqlite.org/forum/forumpost/d77281aec2df9ada
Summary: there are opinions that sqlite3_column_text() and
sqlite3_value_text() should handle strings such that embedded
NULs are retained. This block does that. This block does _not_
apply that special-case behavior to any number of _other_
APIs which return C-strings. That discrepancy makes this
block highly arguable, but one can also argue that these two
specific functions can get away with such acrobatics without
it being called voodoo in a pejorative sense.
*/
const argStmt = wasm.xWrap.argAdapter('sqlite3_stmt*'),
argInt = wasm.xWrap.argAdapter('int'),
argValue = wasm.xWrap.argAdapter('sqlite3_value*'),
newStr =
(cstr,n)=>wasm.typedArrayToString(wasm.heap8u(),
Number(cstr), Number(cstr)+n)
capi.sqlite3_column_text = function(stmt, colIndex){
const a0 = argStmt(stmt), a1 = argInt(colIndex);
const cstr = wasm.exports.sqlite3_column_text(a0, a1);
return cstr
? newStr(cstr,wasm.exports.sqlite3_column_bytes(a0, a1))
: null;
};
capi.sqlite3_value_text = function(val){
const a0 = argValue(val);
const cstr = wasm.exports.sqlite3_value_text(a0);
return cstr
? newStr(cstr,wasm.exports.sqlite3_value_bytes(a0))
: null;
};
}/*text-return-related bindings*/
//#endif proxy-text-apis
{/* sqlite3_config() */
/**
Wraps a small subset of the C API's sqlite3_config() options.
@@ -1836,6 +1881,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
for anything other than local/sessionStorage. It "can"
be used that way but it's not really intended to be. */
capi.sqlite3_vfs_unregister(pKvvfs);
delete capi.sqlite3_kvvfs_methods;
}
}/*pKvvfs*/
@@ -1944,7 +1990,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
tgt[memKey] = fProxy;
}else{
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name));
const pFunc = wasm.installFunction(fProxy, sigN);
tgt[memKey] = pFunc;
if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){
tgt.addOnDispose('ondispose.__removeFuncList handler',
+160 -126
View File
@@ -27,13 +27,14 @@
/**
sqlite3ApiBootstrap() is the only global symbol persistently
exposed by this API. It is intended to be called one time at the
end of the API amalgamation process, passed configuration details
for the current environment, and then optionally be removed from
the global object using `delete globalThis.sqlite3ApiBootstrap`.
end of the API amalgamation process and passed configuration details
for the current environment.
This function is not intended for client-level use. It is intended
for use in creating bundles configured for specific WASM
environments.
environments. That said, the "sqlite3-api.js" intermediary build
file aims to be suitable for dropping in to custom builds, and it
exposes only this function.
This function expects a configuration object, intended to abstract
away details specific to any given WASM environment, primarily so
@@ -93,9 +94,10 @@
can be replaced with (e.g.) empty functions to squelch all such
output.
- `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the OPFS-backed
filesystem in WASMFS-capable builds.
- `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the
OPFS-backed filesystem in WASMFS-capable builds. This is only
used in WASMFS-capable builds of the library (which the canonical
builds do not include).
[^1] = This property may optionally be a function, in which case
this function calls that function to fetch the value,
@@ -125,7 +127,8 @@
Both sqlite3ApiBootstrap.defaultConfig and
globalThis.sqlite3ApiConfig get deleted by sqlite3ApiBootstrap()
because any changes to them made after that point would have no
useful effect.
useful effect. This function also deletes itself from globalThis
when it's called.
This function returns a Promise to the sqlite3 namespace object,
which resolves after the async pieces of the library init are
@@ -177,14 +180,6 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
}
});
/**
Eliminate any confusion about whether these config objects may
be used after library initialization by eliminating the outward-facing
objects...
*/
delete globalThis.sqlite3ApiConfig;
delete sqlite3ApiBootstrap.defaultConfig;
/**
The main sqlite3 binding API gets installed into this object,
mimicking the C API as closely as we can. The numerous members
@@ -796,25 +791,10 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
/**
wasm.X properties which are used for configuring the wasm
environment via whwashutil.js.
environment via whwashutil.js. This object gets fleshed out with
a number of WASM-specific utilities, in sqlite3-api-glue.c-pp.js.
*/
Object.assign(wasm, {
/**
The WASM IR (Intermediate Representation) value for
pointer-type values. If set then it MUST be one of 'i32' or
'i64' (else an exception will be thrown). If it's not set, it
will default to 'i32'.
*/
pointerIR: config.wasmPtrIR,
/**
True if BigInt support was enabled via (e.g.) the
Emscripten -sWASM_BIGINT flag, else false. When
enabled, certain 64-bit sqlite3 APIs are enabled which
are not otherwise enabled due to JS/WASM int64
impedance mismatches.
*/
bigIntEnabled: !!config.bigIntEnabled,
/**
The symbols exported by the WASM environment.
@@ -825,8 +805,9 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
/**
When Emscripten compiles with `-sIMPORTED_MEMORY`, it
initializes the heap and imports it into wasm, as opposed to
the other way around. In this case, the memory is not
available via this.exports.memory.
the other way around. In this case, the memory is not available
via this.exports.memory so the client must pass it in via
config.memory.
*/
memory: config.memory
|| config.exports['memory']
@@ -834,6 +815,29 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
"in either config.exports.memory (exported)",
"or config.memory (imported)."),
/**
The WASM pointer size. If set then it MUST be one of 4 or 8 and
it MUST correspond to the WASM environment's pointer size. We
figure out the size by calling some un-JS-wrapped WASM function
which returns a pointer-type value. If that value is a BigInt,
it's 64-bit, else it's 32-bit. The pieces which populate
sqlite3.wasm (whwasmutil.js) can figure this out _if_ they can
allocate, but we have a chicken/egg situation there which makes
it illegal for that code to invoke wasm.dealloc() at the time
it would be needed. So we need to configure it ahead of time
(here) instead.
*/
pointerSize: ('number'===typeof config.exports.sqlite3_libversion()) ? 4 : 8,
/**
True if BigInt support was enabled via (e.g.) the
Emscripten -sWASM_BIGINT flag, else false. When
enabled, certain 64-bit sqlite3 APIs are enabled which
are not otherwise enabled due to JS/WASM int64
impedance mismatches.
*/
bigIntEnabled: !!config.bigIntEnabled,
/**
WebAssembly.Table object holding the indirect function call
table. Defaults to exports.__indirect_function_table.
@@ -949,7 +953,11 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
};
wasm.realloc.impl = wasm.exports[keyRealloc];
wasm.dealloc = function f(m){
f.impl(wasm.ptr.coerce(m)/*tag:64bit*/);
f.impl(wasm.ptr.coerce(m)/*tag:64bit*/)
/* This coerce() is the reason we have to set wasm.pointerSize before
calling WhWasmUtilInstaller(). If we don't, that code will call
into this very early in its init, before wasm.ptr has been set up,
resulting in a null deref here. */;
};
wasm.dealloc.impl = wasm.exports[keyDealloc];
}
@@ -1020,18 +1028,18 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
}/*compileOptionUsed()*/;
/**
sqlite3.wasm.pstack (pseudo-stack) holds a special-case intended
solely for short-lived, small data. In practice, it's primarily
used to allocate output pointers. It mus not be used for any
memory which needs to outlive the scope in which it's obtained
from pstack.
sqlite3.wasm.pstack (pseudo-stack) holds a special-case allocator
intended solely for short-lived, small data. In practice, it's
primarily used to allocate output pointers. It must not be used
for any memory which needs to outlive the scope in which it's
obtained from pstack.
The library guarantees only that a minimum of 2kb are available
in this allocator, and it may provide more (it's a build-time
value). pstack.quota and pstack.remaining can be used to get the
total resp. remaining amount of memory.
It has only a single intended usage:
It has only a single intended usage pattern:
```
const stackPos = pstack.pointer;
@@ -1048,13 +1056,11 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
```
This allocator is much faster than a general-purpose one but is
limited to usage patterns like the one shown above.
limited to usage patterns like the one shown above (which are
pretty common when using sqlite3.capi).
It operates from a static range of memory which lives outside of
space managed by Emscripten's stack-management, so does not
collide with Emscripten-provided stack allocation APIs. The
memory lives in the WASM heap and can be used with routines such
as wasm.poke() and wasm.heap8u().slice().
The memory lives in the WASM heap and can be used with routines
such as wasm.poke() and wasm.heap8u().slice().
*/
wasm.pstack = Object.assign(Object.create(null),{
/**
@@ -1128,7 +1134,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
argument: if it's 1, it returns a single pointer value. If it's
more than 1, it returns the same as allocChunks().
When a returned pointers will refer to a 64-bit value, e.g. a
When a returned pointer will refer to a 64-bit value, e.g. a
double or int64, and that value must be written or fetched,
e.g. using wasm.poke() or wasm.peek(), it is
important that the pointer in question be aligned to an 8-byte
@@ -1196,6 +1202,9 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
}
})/*wasm.pstack properties*/;
/**
Docs: https://sqlite.org/wasm/doc/trunk/api-c-style.md#sqlite3_randomness
*/
capi.sqlite3_randomness = (...args)=>{
if(1===args.length
&& util.isTypedArray(args[0])
@@ -1230,8 +1239,6 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
wasm.exports.sqlite3_randomness(...args);
};
/** State for sqlite3_wasmfs_opfs_dir(). */
let __wasmfsOpfsDir = undefined;
/**
If the wasm environment has a WASMFS/OPFS-backed persistent
storage directory, its path is returned by this function. If it
@@ -1255,7 +1262,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
WASMFS capability requires a custom build.
*/
capi.sqlite3_wasmfs_opfs_dir = function(){
if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
if(undefined !== this.dir) return this.dir;
// If we have no OPFS, there is no persistent dir
const pdir = config.wasmfsOpfsDir;
if(!pdir
@@ -1263,21 +1270,21 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
|| !globalThis.FileSystemDirectoryHandle
|| !globalThis.FileSystemFileHandle
|| !wasm.exports.sqlite3__wasm_init_wasmfs){
return __wasmfsOpfsDir = "";
return this.dir = "";
}
try{
if(pdir && 0===wasm.xCallWrapped(
'sqlite3__wasm_init_wasmfs', 'i32', ['string'], pdir
)){
return __wasmfsOpfsDir = pdir;
return this.dir = pdir;
}else{
return __wasmfsOpfsDir = "";
return this.dir = "";
}
}catch(e){
// sqlite3__wasm_init_wasmfs() is not available
return __wasmfsOpfsDir = "";
return this.dir = "";
}
};
}.bind(Object.create(null));
/**
Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
@@ -1333,7 +1340,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
*/
capi.sqlite3_js_vfs_list = function(){
const rc = [];
let pVfs = capi.sqlite3_vfs_find(wasm.ptr.coerce(0));
let pVfs = capi.sqlite3_vfs_find(wasm.ptr.null);
while(pVfs){
const oVfs = new capi.sqlite3_vfs(pVfs);
rc.push(wasm.cstrToJs(oVfs.$zName));
@@ -1953,55 +1960,58 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
return (0===v) ? undefined : capi.sqlite3_value_to_js(v, throwIfCannotConvert);
};
/**
Internal impl of sqlite3_preupdate_new/old_js() and
sqlite3changeset_new/old_js().
*/
const __newOldValue = function(pObj, iCol, impl){
impl = capi[impl];
if(!this.ptr) this.ptr = wasm.allocPtr();
else wasm.pokePtr(this.ptr, 0);
const rc = impl(pObj, iCol, this.ptr);
if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
const pv = wasm.peekPtr(this.ptr);
return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
}.bind(Object.create(null));
if( true ){ /* changeset/preupdate additions... */
/**
Internal impl of sqlite3_preupdate_new/old_js() and
sqlite3changeset_new/old_js().
*/
const __newOldValue = function(pObj, iCol, impl){
impl = capi[impl];
if(!this.ptr) this.ptr = wasm.allocPtr();
else wasm.pokePtr(this.ptr, 0);
const rc = impl(pObj, iCol, this.ptr);
if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
const pv = wasm.peekPtr(this.ptr);
return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
}.bind(Object.create(null));
/**
A wrapper around sqlite3_preupdate_new() which fetches the
sqlite3_value at the given index and returns the result of
passing it to sqlite3_value_to_js(). Throws on error.
*/
capi.sqlite3_preupdate_new_js =
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_new');
/**
A wrapper around sqlite3_preupdate_new() which fetches the
sqlite3_value at the given index and returns the result of
passing it to sqlite3_value_to_js(). Throws on error.
*/
capi.sqlite3_preupdate_new_js =
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_new');
/**
The sqlite3_preupdate_old() counterpart of
sqlite3_preupdate_new_js(), with an identical interface.
*/
capi.sqlite3_preupdate_old_js =
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_old');
/**
The sqlite3_preupdate_old() counterpart of
sqlite3_preupdate_new_js(), with an identical interface.
*/
capi.sqlite3_preupdate_old_js =
(pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_old');
/**
A wrapper around sqlite3changeset_new() which fetches the
sqlite3_value at the given index and returns the result of
passing it to sqlite3_value_to_js(). Throws on error.
/**
A wrapper around sqlite3changeset_new() which fetches the
sqlite3_value at the given index and returns the result of
passing it to sqlite3_value_to_js(). Throws on error.
If sqlite3changeset_new() succeeds but has no value to report,
this function returns the undefined value, noting that undefined
is a valid conversion from an `sqlite3_value`, so is unambiguous.
*/
capi.sqlite3changeset_new_js =
(pChangesetIter, iCol) => __newOldValue(pChangesetIter, iCol,
'sqlite3changeset_new');
If sqlite3changeset_new() succeeds but has no value to report,
this function returns the undefined value, noting that
undefined is not a valid conversion from an `sqlite3_value`, so
is unambiguous.
*/
capi.sqlite3changeset_new_js =
(pChangesetIter, iCol) => __newOldValue(pChangesetIter, iCol,
'sqlite3changeset_new');
/**
The sqlite3changeset_old() counterpart of
sqlite3changeset_new_js(), with an identical interface.
*/
capi.sqlite3changeset_old_js =
(pChangesetIter, iCol)=>__newOldValue(pChangesetIter, iCol,
'sqlite3changeset_old');
/**
The sqlite3changeset_old() counterpart of
sqlite3changeset_new_js(), with an identical interface.
*/
capi.sqlite3changeset_old_js =
(pChangesetIter, iCol)=>__newOldValue(pChangesetIter, iCol,
'sqlite3changeset_old');
}/*changeset/preupdate additions*/
/* The remainder of the API will be set up in later steps. */
const sqlite3 = {
@@ -2013,10 +2023,10 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
config,
/**
Holds the version info of the sqlite3 source tree from which
the generated sqlite3-api.js gets built. Note that its version
may well differ from that reported by sqlite3_libversion(), but
that should be considered a source file mismatch, as the JS and
WASM files are intended to be built and distributed together.
the generated sqlite3-api.js gets built. Its version may well
differ from that reported by sqlite3_libversion(), but that
should be considered a source file mismatch, as the JS and WASM
files are intended to be built and distributed together.
This object is initially a placeholder which gets replaced by a
build-generated object.
@@ -2041,9 +2051,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
async init will be fatal to the init as a whole, but init
routines are themselves welcome to install dummy catch()
handlers which are not fatal if their failure should be
considered non-fatal. If called more than once, the second and
subsequent calls are no-ops which return a pre-resolved
Promise.
considered non-fatal.
Ideally this function is called as part of the Promise chain
which handles the loading and bootstrapping of the API. If not
@@ -2060,18 +2068,14 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
*/
asyncPostInit: async function ff(){
if(ff.isReady instanceof Promise) return ff.isReady;
let lia = sqlite3ApiBootstrap.initializersAsync;
delete sqlite3ApiBootstrap.initializersAsync;
let lia = this.initializersAsync;
delete this.initializersAsync;
const postInit = async ()=>{
if(!sqlite3.__isUnderTest){
/* Delete references to internal-only APIs which are used by
some initializers. Retain them when running in test mode
so that we can add tests for them. */
delete sqlite3.util;
/* It's conceivable that we might want to expose
StructBinder to client-side code, but it's only useful if
clients build their own sqlite3.wasm which contains their
own C struct types. */
delete sqlite3.StructBinder;
}
return sqlite3;
@@ -2090,7 +2094,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
let p = Promise.resolve(sqlite3);
while(lia.length) p = p.then(lia.shift());
return ff.isReady = p.catch(catcher);
},
}.bind(sqlite3ApiBootstrap),
/**
scriptInfo ideally gets injected into this object by the
infrastructure which assembles the JS/WASM module. It contains
@@ -2117,16 +2121,37 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
}
delete sqlite3ApiBootstrap.initializers;
sqlite3ApiBootstrap.sqlite3 = sqlite3;
delete globalThis.sqlite3ApiBootstrap;
delete globalThis.sqlite3ApiConfig;
sqlite3InitScriptInfo.debugModule(
"sqlite3ApiBootstrap() complete", sqlite3
);
sqlite3.scriptInfo /* used by some async init code */ =
sqlite3InitScriptInfo /* from post-js-header.js */;
if( (sqlite3.__isUnderTest = sqlite3IsUnderTest /* from post-js-header.js */) ){
sqlite3.config.emscripten = EmscriptenModule;
const iw = sqlite3InitScriptInfo.instantiateWasm;
if( 'undefined'!==typeof sqlite3InitScriptInfo/* from post-js-header.js */ ){
sqlite3InitScriptInfo.debugModule(
"sqlite3ApiBootstrap() complete", sqlite3
);
sqlite3.scriptInfo
/* Used by some async init code. As of 2025-11-15 this is still
in use by the OPFS VFS for locating its worker. In non-Emscripten
builds, this would need to be injected in somewhere to get
that VFS loading. */ = sqlite3InitScriptInfo;
}
sqlite3.__isUnderTest =
('undefined'===typeof sqlite3IsUnderTest /* from post-js-header.js */)
? false : !!sqlite3IsUnderTest;
if( sqlite3.__isUnderTest ){
if( 'undefined'!==typeof EmscriptenModule ){
sqlite3.config.emscripten = EmscriptenModule;
}
/*
The problem with exposing these pieces (in non-testing runs) via
sqlite3.wasm is that it exposes non-SQLite pieces to the
clients, who may come to expect it to remain. _We_ only have
these data because we've overridden Emscripten's wasm file
loader, and if we lose that capability for some reason then
we'll lose access to this metadata.
These data are interesting for exploring how the wasm/JS
pieces connect, e.g. for exploring exactly what Emscripten
imports into WASM from its JS glue, but it's not
SQLite-related.
*/
const iw = sqlite3.scriptInfo?.instantiateWasm;
if( iw ){
/* Metadata injected by the custom Module.instantiateWasm()
in pre-js.c-pp.js. */
@@ -2135,6 +2160,15 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
sqlite3.wasm.imports = iw.imports;
}
}
/**
Eliminate any confusion about whether these config objects may
be used after library initialization by eliminating the outward-facing
objects...
*/
delete globalThis.sqlite3ApiConfig;
delete globalThis.sqlite3ApiBootstrap;
delete sqlite3ApiBootstrap.defaultConfig;
return sqlite3.asyncPostInit().then((s)=>{
sqlite3InitScriptInfo.debugModule(
"sqlite3.asyncPostInit() complete", sqlite3
+2 -2
View File
@@ -16,7 +16,7 @@
asynchronous Origin-Private FileSystem (OPFS) APIs using a second
Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
intended to be appended to the main sqlite3 JS deliverable somewhere
after sqlite3-api-oo1.js and before sqlite3-api-cleanup.js.
after sqlite3-api-oo1.js.
*/
'use strict';
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
@@ -1441,7 +1441,7 @@ installOpfsVfs.defaultProxyUri =
globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
try{
let proxyJs = installOpfsVfs.defaultProxyUri;
if(sqlite3.scriptInfo.sqlite3Dir){
if( sqlite3?.scriptInfo?.sqlite3Dir ){
installOpfsVfs.defaultProxyUri =
sqlite3.scriptInfo.sqlite3Dir + proxyJs;
//sqlite3.config.warn("installOpfsVfs.defaultProxyUri =",installOpfsVfs.defaultProxyUri);
+3 -3
View File
@@ -136,8 +136,8 @@
/*
** If SQLITE_WASM_BARE_BONES is defined, undefine most of the ENABLE
** macros. This will, when using the canonical makefile, also elide
** any C functions from the WASM exports which are listed in
** ./EXPORT_FUNCTIONS.sqlite3-extras.
** any C functions from the WASM exports: see
** ./EXPORTED_FUNCTIONS.c-pp.
*/
#ifdef SQLITE_WASM_BARE_BONES
# undef SQLITE_ENABLE_COLUMN_METADATA
@@ -326,7 +326,7 @@ SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_ptr(void){
*/
SQLITE_WASM_EXPORT void sqlite3__wasm_pstack_restore(unsigned char * p){
assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos);
assert(0==((unsigned long long)p & 0x7));
assert(0==((unsigned long long)p & 0x7) /* 8-byte aligned */);
if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){
PStack.pPos = p;
}
+53 -16
View File
@@ -270,9 +270,10 @@ static void db_prepare(sqlite3_stmt **pStmt, const char * zSql, ...);
/*
** Opens the given file and processes its contents as c-pp, sending
** all output to the global c-pp output channel. Fails fatally on
** error.
** error. If bRaw is true then the file's contents are passed through
** verbatim, rather than being preprocessed.
*/
static void cmpp_process_file(const char * zName);
static void cmpp_process_file(const char * zName, int bRaw);
/*
** Operator policy for cmpp_kvp_parse().
@@ -970,7 +971,6 @@ void db_prepare(sqlite3_stmt **pStmt, const char * zSql, ...){
char * z = 0;
int n = 0;
va_list va;
if(!str) fatal("sqlite3_str_new() failed");
va_start(va, zSql);
sqlite3_str_vappendf(str, zSql, va);
va_end(va);
@@ -2213,12 +2213,23 @@ static void cmpp_kwd_endif(CmppKeyword const * pKw, CmppTokenizer *t){
static void cmpp_kwd_include(CmppKeyword const * pKw, CmppTokenizer *t){
char const * zFile;
char * zResolved;
int bRaw = 0 /* -raw flag */;
if(CT_skip(t)) return;
else if(t->args.argc!=2){
cmpp_kwd__err(pKw, t, "Expecting exactly 1 filename argument");
else if(t->args.argc<2 || t->args.argc>3){
cmpp_kwd__err(pKw, t, "Expected args: ?-raw? filename");
}
zFile = (const char *)t->args.argv[1];
if(db_including_has(zFile)){
if(t->args.argc==2){
zFile = (const char *)t->args.argv[1];
}else{
if( 0==strcmp("-raw", (char*)t->args.argv[1]) ){
bRaw = 1;
}else{
cmpp_kwd__err(pKw, t, "Unhandled argument: %s",
t->args.argv[1]);
}
zFile = (const char *)t->args.argv[2];
}
if(!bRaw && db_including_has(zFile)){
/* Note that different spellings of the same filename
** will elude this check, but that seems okay, as different
** spellings means that we're not re-running the exact same
@@ -2229,16 +2240,15 @@ static void cmpp_kwd_include(CmppKeyword const * pKw, CmppTokenizer *t){
}
zResolved = db_include_search(zFile);
if(zResolved){
db_including_add(zFile, t->zName, t->token.lineNo);
cmpp_process_file(zResolved);
db_include_rm(zFile);
if( bRaw ) db_including_add(zFile, t->zName, t->token.lineNo);
cmpp_process_file(zResolved, bRaw);
if( bRaw ) db_include_rm(zFile);
db_free(zResolved);
}else{
cmpp_t__err(t, "file not found: %s", zFile);
}
}
static void cmpp_dump_defines( FILE * fp, int bIndent ){
sqlite3_stmt * const q = g_stmt(GStmt_defSelAll);
while( SQLITE_ROW==sqlite3_step(q) ){
@@ -2392,7 +2402,7 @@ CmppKeyword aKeywords[] = {
{S(Endif), 0, TT_Endif, cmpp_kwd_endif},
{S(Error), 0, TT_Error, cmpp_kwd_error},
{S(If), 1, TT_If, cmpp_kwd_if},
{S(Include), 0, TT_Include, cmpp_kwd_include},
{S(Include), 1, TT_Include, cmpp_kwd_include},
{S(Pragma), 1, TT_Pragma, cmpp_kwd_pragma},
{S(Savepoint), 1, TT_Savepoint, cmpp_kwd_savepoint},
{S(Stderr), 0, TT_Stderr, cmpp_kwd_stderr},
@@ -2444,14 +2454,25 @@ void cmpp_process_string(const char * zName,
g.tok = oldTok;
}
void cmpp_process_file(const char * zName){
void cmpp_process_file(const char * zName, int bRaw){
FileWrapper fw = FileWrapper_empty;
FileWrapper_open(&fw, zName, "r");
g_FileWrapper_link(&fw);
FileWrapper_slurp(&fw);
g_debug(1,("Read %u byte(s) from [%s]\n", fw.nContent, fw.zName));
if( fw.zContent ){
cmpp_process_string(zName, fw.zContent, fw.nContent);
if( bRaw ){
FileWrapper fw = FileWrapper_empty;
FileWrapper_open(&fw, zName, "rb");
g_FileWrapper_link(&fw);
FileWrapper_slurp(&fw);
if( 1!=fwrite(fw.zContent, fw.nContent, 1, g.out.pFile) ){
fatal("fwrite() failed with errno %d\n", errno);
}
g_FileWrapper_close(&fw);
}else{
cmpp_process_string(zName, fw.zContent, fw.nContent);
}
}
g_FileWrapper_close(&fw);
}
@@ -2580,6 +2601,21 @@ static int arg_is_flag( char const *zFlag, char const *zArg,
return 0;
}
static void define_argv(int argc, char const * const * argv){
sqlite3_str * const s = sqlite3_str_new(g.db);
sqlite3_str_append(s, "c-pp::ARGV=", 11);
for( int i = 0; i < argc; ++i ){
if( i ) sqlite3_str_appendchar(s, 1, ' ');
sqlite3_str_appendf(s, "%s", argv[i]);
}
char * const z = sqlite3_str_finish(s);
assert(z);
if(z){
db_define_add(z, NULL);
sqlite3_free(z);
}
}
int main(int argc, char const * const * argv){
int rc = 0;
int inclCount = 0;
@@ -2617,6 +2653,7 @@ int main(int argc, char const * const * argv){
g.sqlTrace.expandSql = expandMode;
}
cmpp_initdb();
define_argv(argc, argv);
}
for(int i = 1; i < argc; ++i){
int negate = 0;
@@ -2674,7 +2711,7 @@ int main(int argc, char const * const * argv){
DOIT {
++nFile;
g_out_open;
cmpp_process_file(zVal);
cmpp_process_file(zVal, 0);
}
}
ISFLAG("e"){
@@ -2757,7 +2794,7 @@ int main(int argc, char const * const * argv){
++inclCount;
}
FileWrapper_open(&g.out, g.out.zName, "w");
cmpp_process_file("-");
cmpp_process_file("-", 0);
}
}
}
+17 -8
View File
@@ -227,6 +227,14 @@ globalThis.WhWasmUtilInstaller = function(target){
all args with a space between each. */
const toss = (...args)=>{throw new Error(args.join(' '))};
if( !target.pointerSize && !target.pointerIR
&& target.alloc && target.dealloc ){
/* Try to determine the pointer size by allocating. */
const ptr = target.alloc(1);
target.pointerSize = ('bigint'===typeof ptr ? 8 : 4);
target.dealloc(ptr);
}
/**
As of 2025-09-21, this library works with 64-bit WASM modules
built with Emscripten's -sMEMORY64=1.
@@ -659,12 +667,14 @@ globalThis.WhWasmUtilInstaller = function(target){
const ft = target.functionTable();
const oldLen = __asPtrType(ft.length);
let ptr;
while(cache.freeFuncIndexes.length){
ptr = cache.freeFuncIndexes.pop();
if(ft.get(ptr)){ /* Table was modified via a different API */
while( (ptr = cache.freeFuncIndexes.pop()) ){
if(ft.get(ptr)){
/* freeFuncIndexes's entry is stale. Table was modified via a
different API */
ptr = null;
continue;
}else{
/* This index is free. We'll re-use it. */
break;
}
}
@@ -755,10 +765,9 @@ globalThis.WhWasmUtilInstaller = function(target){
has no side effects and returns undefined.
*/
target.uninstallFunction = function(ptr){
if(!ptr && 0!==ptr) return undefined;
const fi = cache.freeFuncIndexes;
if(!ptr && __NullPtr!==ptr) return undefined;
const ft = target.functionTable();
fi.push(ptr);
cache.freeFuncIndexes.push(ptr);
const rc = ft.get(ptr);
ft.set(ptr, null);
return rc;
@@ -996,12 +1005,12 @@ globalThis.WhWasmUtilInstaller = function(target){
target.heap8u().
*/
target.cstrlen = function(ptr){
if(!ptr || !target.isPtr(ptr)) return null;
if(!ptr || !target.isPtr/*64*/(ptr)) return null;
ptr = Number(ptr) /*tag:64bit*/;
const h = heapWrappers().HEAP8U;
let pos = ptr;
for( ; h[pos] !== 0; ++pos ){}
return Number(pos - ptr);
return pos - ptr;
};
/** Internal helper to use in operations which need to distinguish
+365 -96
View File
@@ -32,7 +32,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
if(!(config.heap instanceof WebAssembly.Memory)
&& !(config.heap instanceof Function)){
toss("config.heap must be WebAssembly.Memory instance or a function.");
toss("config.heap must be WebAssembly.Memory instance or a function which returns one.");
}
['alloc','dealloc'].forEach(function(k){
(config[k] instanceof Function) ||
@@ -48,14 +48,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
memberSuffix = (config.memberSuffix || ""),
BigInt = globalThis['BigInt'],
BigInt64Array = globalThis['BigInt64Array'],
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array,
ptrIR = config.pointerIR
|| config.ptrIR/*deprecated*/
|| 'i32',
/* Undocumented (on purpose) config options: */
ptrSize = config.ptrSize/*deprecated*/
|| ('i32'===ptrIR ? 4 : 8)
;
bigIntEnabled = config.bigIntEnabled ?? !!BigInt64Array;
//console.warn("config",config);
let ptr = alloc(1);
const ptrIR = config.pointerIR
|| config.ptrIR/*deprecated*/
|| ('bigint'===typeof ptr ? 'i64' : 'i32');
/* Undocumented (on purpose) config options: */
const ptrSize = config.ptrSize/*deprecated*/
|| ('i32'===ptrIR ? 4 : 8);
dealloc(ptr);
ptr = undefined;
//console.warn("ptrIR =",ptrIR,"ptrSize =",ptrSize);
if(ptrIR!=='i32' && ptrIR!=='i64') toss("Invalid pointer representation:",ptrIR);
if(ptrSize!==4 && ptrSize!==8) toss("Invalid pointer size:",ptrSize);
@@ -136,11 +141,11 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
/** True if SIG s looks like a function signature, else
false. */
const isFuncSig = (s)=>'('===s[1];
/** True if SIG s is-a pointer signature. */
const isPtrSig = (s)=>'p'===s || 'P'===s;
/** True if SIG s is-a pointer-type signature. */
const isPtrSig = (s)=>'p'===s || 'P'===s || 's'===s;
const isAutoPtrSig = (s)=>'P'===s /*EXPERIMENTAL*/;
/** Returns p if SIG s is a function SIG, else returns s[0]. */
const sigLetter = (s)=>isFuncSig(s) ? 'p' : s[0];
const sigLetter = (s)=>s ? (isFuncSig(s) ? 'p' : s[0]) : undefined;
/** Returns the WASM IR form of the Emscripten-conventional letter
at SIG s[0]. Throws for an unknown SIG. */
const sigIR = function(s){
@@ -154,6 +159,19 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
}
toss("Unhandled signature IR:",s);
};
/** Returns the WASM sizeof of the Emscripten-conventional letter
at SIG s[0]. Throws for an unknown SIG. */
const sigSize = function(s){
switch(sigLetter(s)){
case 'c': case 'C': return 1;
case 'i': return 4;
case 'p': case 'P': case 's': return ptrSize;
case 'j': return 8;
case 'f': return 4;
case 'd': return 8;
}
toss("Unhandled signature sizeof:",s);
};
const affirmBigIntArray = BigInt64Array
? ()=>true : ()=>toss('BigInt64Array is not available.');
@@ -232,11 +250,22 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
accessible via boundObject.pointer, which is gated behind a
property interceptor, but are not exposed anywhere else in the
object.
This approach means we cannot proxy arrays, or any type which
might be realloced, as that pointer could change out from under
us. That's not an issue for nested structs, but it might be for a
struct they're embedded in. In the case of nested structs we
"could" record their top-most parent object and their offset into
that object, instead of storing the pointer itself. We could that
by allowing a function instead of a pointer in this map, that
function returning the (lazily-calculated) address. Hmm.
*/
const __instancePointerMap = new WeakMap();
const getInstancePtr = (obj)=>__instancePointerMap.get(obj);
/** Property name for the pointer-is-external marker. */
const xPtrPropName = '(pointer-is-external)';
const xPtrPropName = Symbol('(pointer-is-external)');
const __isPtr32 = (ptr)=>('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
const __isPtr64 = (ptr)=>(
@@ -252,7 +281,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
/** Frees the obj.pointer memory and clears the pointer
property. */
const __freeStruct = function(ctor, obj, m){
if(!m) m = __instancePointerMap.get(obj);
if(!m) m = getInstancePtr(obj);
if(m) {
__instancePointerMap.delete(obj);
if(Array.isArray(obj.ondispose)){
@@ -283,7 +312,12 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
ctor.structName,"instance:",
ctor.structInfo.sizeof,"bytes @"+m);
}
if(!obj[xPtrPropName]) dealloc(m);
if(!obj[xPtrPropName]){
if( ctor.structInfo.zeroOnFree ){
heap().fill(0, Number(m), Number(m)+ctor.structInfo.sizeof);
}
dealloc(m);
}
}
};
@@ -324,8 +358,69 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
: null;
};
/** True if sig looks like an emscripten/jaccwabyt
type signature, else false. */
const looksLikeASig = function f(sig){
f.rxSig1 ??= /^[ipPsjfdcC]$/;
f.rxSig2 ??= /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
return f.rxSig1.test(sig) || f.rxSig2.test(sig);
};
/** Returns a pair of adaptor maps (objects) in a length-3
array specific to the given object. */
const __adaptorsFor = function(who){
let x = this.get(who);
if( !x ){
x = [ Object.create(null), Object.create(null), Object.create(null) ];
this.set(who, x);
}
return x;
}.bind(new WeakMap);
/** Code de-duplifier for __adaptGet(), __adaptSet(), and
__adaptStruct(). */
const __adaptor = function(who, which, key, proxy){
const a = __adaptorsFor(who)[which];
if(3===arguments.length) return a[key];
if( proxy ) return a[key] = proxy;
return delete a[key];
};
const noopAdapter = (x)=>x;
// StructBinder::adaptGet()
const __adaptGet = function(key, ...args){
/*if( looksLikeASig(key) ){
toss("Getter adaptor's name (",key,") collides with a data type signature.");
}*/
return __adaptor(this, 0, key, ...args);
};
// StructBinder::adaptSet()
const __adaptSet = function(key, ...args){
if( looksLikeASig(key) ){
toss("Setter adaptor's name (",key,") collides with a data type signature.");
}
return __adaptor(this, 1, key, ...args);
};
// StructBinder::adaptStruct()
const __adaptStruct = function(key, ...args){
return __adaptor(this, 2, key, ...args);
};
const __adaptStruct2 = function(who,key){
const si = ('string'===typeof key)
? __adaptor(who, 2, key) : key;
if( 'object'!==typeof si ){
toss("Invalid struct mapping object. Arg =",key,JSON.stringify(si));
}
return si;
};
const __memberKey = (k)=>memberPrefix + k + memberSuffix;
const __memberKeyProp = rop(__memberKey);
//const __adaptGetProp = rop(__adaptGet);
/**
Looks up a struct member in structInfo.members. Throws if found
@@ -342,7 +437,8 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
if(v.key===memberName){ m = v; break; }
}
if(!m && tossIfNotFound){
toss(sPropName(structInfo.name,memberName),'is not a mapped struct member.');
toss(sPropName(structInfo.name || structInfo.structName, memberName),
'is not a mapped struct member.');
}
}
return m;
@@ -361,7 +457,7 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
const __ptrPropDescriptor = {
configurable: false, enumerable: false,
get: function(){return __instancePointerMap.get(this)},
get: function(){return getInstancePtr(this)},
set: ()=>toss("Cannot assign the 'pointer' property of a struct.")
// Reminder: leaving `set` undefined makes assignments
// to the property _silently_ do nothing. Current unit tests
@@ -558,78 +654,176 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
});
/**
Pass this a StructBinder-generated prototype, and the struct
member description object. It will define property accessors for
proto[memberKey] which read from/write to memory in
this.pointer. It modifies descr to make certain downstream
operations much simpler.
If struct description object si has a getter proxy, return it (a
function), else return undefined.
*/
const makeMemberWrapper = function f(ctor,name, descr){
const memberGetterProxy = function(si){
return si.get || (si.adaptGet
? StructBinder.adaptGet(si.adaptGet)
: undefined);
};
/**
If struct description object si has a setter proxy, return it (a
function), else return undefined.
*/
const memberSetterProxy = function(si){
return si.set || (si.adaptSet
? StructBinder.adaptSet(si.adaptSet)
: undefined);
};
/**
To be called by makeMemberWrapper() when si has a 'members'
member, i.e. is an embedded struct. This function sets up that
struct like any other and also sets up property accessor for
ctor.memberKey(name) which returns an instance of that new
StructType when the member is accessed. That instance wraps the
memory of the member's part of the containing C struct instance.
That is, if struct Foo has member bar which is an inner struct
then:
const f = new Foo;
const b = f.bar;
assert( b is-a StructType object );
assert( b.pointer === f.b.pointer );
b will be disposed of when f() is. Calling b.dispose() will not
do any permanent harm, as the wrapper object will be recreated
when accessing f.bar, pointing to the same memory in f.
The si.zeroOnFree flag has no effect on embedded structs because
they wrap "external" memory, so do not own it, and are thus never
freed, as such.
*/
const makeMemberStructWrapper = function callee(ctor, name, si){
/**
Where we store inner-struct member proxies. Keys are a
combination of the parent object's pointer address and the
property's name. The values are StructType instances.
*/
const __innerStructs = (callee.innerStructs ??= new Map());
const key = ctor.memberKey(name);
if( undefined!==si.signature ){
toss("'signature' cannot be used on an embedded struct (",
ctor.structName,".",key,").");
}
if( memberSetterProxy(si) ){
toss("'set' and 'adaptSet' are not permitted for nested struct members.");
}
//console.warn("si =",ctor.structName, name, JSON.stringify(si,' '));
si.structName ??= ctor.structName+'::'+name;
si.key = key;
si.name = name;
si.constructor = this.call(this, si.structName, si);
//console.warn("si.constructor =",si.constructor);
//console.warn("si =",si,"ctor=",ctor);
const getterProxy = memberGetterProxy(si);
const prop = Object.assign(Object.create(null),{
configurable: false,
enumerable: false,
set: __propThrowOnSet(ctor/*not si.constructor*/.structName, key),
get: function(){
const dbg = si.constructor.prototype.debugFlags.__flags;
const p = this.pointer;
const k = p+'.'+key;
let s = __innerStructs.get(k);
if(dbg.getter){ log("debug.getter: k =",k); }
if( !s ){
s = new si.constructor(__ptrAdd(p, si.offset));
__innerStructs.set(k, s);
this.addOnDispose(()=>s.dispose());
s.addOnDispose(()=>__innerStructs.delete(k));
//console.warn("Created",k,"proxy");
}
if(getterProxy) s = getterProxy.apply(this,[s,key]);
if(dbg.getter) log("debug.getter: result =",s);
return s;
}
});
Object.defineProperty(ctor.prototype, key, prop);
}/*makeMemberStructWrapper()*/;
/**
Pass this a StructBinderImpl-generated constructor, a member
property name, and the struct member description object. It will
define property accessors for proto[memberKey] which read
from/write to memory in this.pointer. It modifies si to make
certain downstream operations simpler.
*/
const makeMemberWrapper = function f(ctor, name, si){
si = __adaptStruct2(this, si);
if( si.members ){
return makeMemberStructWrapper.call(this, ctor, name, si);
}
if(!f._){
/*cache all available getters/setters/set-wrappers for
direct reuse in each accessor function. */
/* Cache all available getters/setters/set-wrappers for
direct reuse in each accessor function. */
f._ = {getters: {}, setters: {}, sw:{}};
const a = ['i','c','C','p','P','s','f','d','v()'];
if(bigIntEnabled) a.push('j');
a.forEach(function(v){
//const ir = sigIR(v);
f._.getters[v] = sigDVGetter(v) /* DataView[MethodName] values for GETTERS */;
f._.setters[v] = sigDVSetter(v) /* DataView[MethodName] values for SETTERS */;
f._.sw[v] = sigDVSetWrapper(v) /* BigInt or Number ctor to wrap around values
for conversion */;
});
const rxSig1 = /^[ipPsjfdcC]$/,
rxSig2 = /^[vipPsjfdcC]\([ipPsjfdcC]*\)$/;
f.sigCheck = function(obj, name, key,sig){
if(Object.prototype.hasOwnProperty.call(obj, key)){
toss(obj.structName,'already has a property named',key+'.');
}
rxSig1.test(sig) || rxSig2.test(sig)
looksLikeASig(sig)
|| toss("Malformed signature for",
sPropName(obj.structName,name)+":",sig);
};
}
const key = ctor.memberKey(name);
f.sigCheck(ctor.prototype, name, key, descr.signature);
descr.key = key;
descr.name = name;
const sigGlyph = sigLetter(descr.signature);
f.sigCheck(ctor.prototype, name, key, si.signature);
si.key = key;
si.name = name;
const sigGlyph = sigLetter(si.signature);
const xPropName = sPropName(ctor.prototype.structName,key);
const dbg = ctor.prototype.debugFlags.__flags;
/*
TODO?: set prototype of descr to an object which can set/fetch
TODO?: set prototype of si to an object which can set/fetch
its preferred representation, e.g. conversion to string or mapped
function. Advantage: we can avoid doing that via if/else if/else
in the get/set methods.
*/
const getterProxy = memberGetterProxy(si);
const prop = Object.create(null);
prop.configurable = false;
prop.enumerable = false;
prop.get = function(){
if(dbg.getter){
log("debug.getter:",f._.getters[sigGlyph],"for", sigIR(sigGlyph),
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof);
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof);
}
let rc = (
new DataView(heap().buffer, Number(this.pointer) + descr.offset, descr.sizeof)
new DataView(heap().buffer, Number(this.pointer) + si.offset, si.sizeof)
)[f._.getters[sigGlyph]](0, isLittleEndian);
if(getterProxy) rc = getterProxy.apply(this,[rc,key]);
if(dbg.getter) log("debug.getter:",xPropName,"result =",rc);
return rc;
};
if(descr.readOnly){
if(si.readOnly){
prop.set = __propThrowOnSet(ctor.prototype.structName,key);
}else{
const setterProxy = memberSetterProxy(si);
prop.set = function(v){
if(dbg.setter){
log("debug.setter:",f._.setters[sigGlyph],"for", sigIR(sigGlyph),
xPropName,'@', this.pointer,'+',descr.offset,'sz',descr.sizeof, v);
xPropName,'@', this.pointer,'+',si.offset,'sz',si.sizeof, v);
}
if(!this.pointer){
toss("Cannot set struct property on disposed instance.");
toss("Cannot set native property on a disposed struct instance.");
}
if(null===v) v = __NullPtr;
else while(!__isPtr(v)){
if(isAutoPtrSig(descr.signature) && (v instanceof StructType)){
if( setterProxy ) v = setterProxy.apply(this,[v]);
if( null===v || undefined===v ) v = __NullPtr;
else while( isPtrSig(si.signature) && !__isPtr(v) ){
if(isAutoPtrSig(si.signature) && (v instanceof StructType)){
// It's a struct instance: let's store its pointer value!
v = v.pointer || __NullPtr;
if(dbg.setter) log("debug.setter:",xPropName,"resolved to",v);
@@ -638,66 +832,45 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
toss("Invalid value for pointer-type",xPropName+'.');
}
(
new DataView(heap().buffer, Number(this.pointer) + descr.offset,
descr.sizeof)
new DataView(heap().buffer, Number(this.pointer) + si.offset,
si.sizeof)
)[f._.setters[sigGlyph]](0, f._.sw[sigGlyph](v), isLittleEndian);
};
}
Object.defineProperty(ctor.prototype, key, prop);
}/*makeMemberWrapper*/;
}/*makeMemberWrapper()*/;
/**
The main factory function which will be returned to the
caller.
caller. The third argument is structly for internal use.
This level of indirection is to avoid that clients can pass a
third argument to this, as that's only for internal use.
internalOpt options:
- None right now. This is for potential use in recursion.
Usages:
StructBinder(string, obj [,optObj]);
StructBinder(obj);
*/
const StructBinder = function StructBinder(structName, structInfo){
if(1===arguments.length){
structInfo = structName;
structName = structInfo.name;
}else if(!structInfo.name){
structInfo.name = structName;
}
if(!structName) toss("Struct name is required.");
let lastMember = false;
Object.keys(structInfo.members).forEach((k)=>{
// Sanity checks of sizeof/offset info...
const m = structInfo.members[k];
if(!m.sizeof) toss(structName,"member",k,"is missing sizeof.");
else if(m.sizeof===1){
(m.signature === 'c' || m.signature === 'C') ||
toss("Unexpected sizeof==1 member",
sPropName(structInfo.name,k),
"with signature",m.signature);
}else{
// sizes and offsets of size-1 members may be odd values, but
// others may not.
if(0!==(m.sizeof%4)){
console.warn("Invalid struct member description =",m,"from",structInfo);
toss(structName,"member",k,"sizeof is not aligned. sizeof="+m.sizeof);
}
if(0!==(m.offset%4)){
console.warn("Invalid struct member description =",m,"from",structInfo);
toss(structName,"member",k,"offset is not aligned. offset="+m.offset);
}
}
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
});
if(!lastMember) toss("No member property descriptions found.");
else if(structInfo.sizeof < lastMember.offset+lastMember.sizeof){
toss("Invalid struct config:",structName,
"max member offset ("+lastMember.offset+") ",
"extends past end of struct (sizeof="+structInfo.sizeof+").");
}
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
/** Constructor for the StructCtor. */
const zeroAsPtr = __asPtrType(0);
const StructBinderImpl = function StructBinderImpl(
structName, si, opt = Object.create(null)
){
/**
StructCtor is the eventual return value of this function. We
need to populate this early on so that we can do some trickery
in feeding it through recursion.
*/
const StructCtor = function StructCtor(externalMemory){
externalMemory = __asPtrType(externalMemory);
//console.warn("externalMemory",externalMemory,arguments[0]);
if(!(this instanceof StructCtor)){
toss("The",structName,"constructor may only be called via 'new'.");
}else if(arguments.length){
if(Number.isNaN(externalMemory) || externalMemory<=zeroAsPtr){
if( !__isPtr(externalMemory) ){
toss("Invalid pointer value",arguments[0],"for",structName,"constructor.");
}
__allocStruct(StructCtor, this, externalMemory);
@@ -705,31 +878,127 @@ globalThis.Jaccwabyt = function StructBinderFactory(config){
__allocStruct(StructCtor, this);
}
};
const self = this;
/**
"Convert" struct description x to a struct description, if
needed.
*/
const ads = (x)=>{
//console.warn("looksLikeASig(",x,") =",looksLikeASig(x));
return (('string'===typeof x) && looksLikeASig(x))
? {signature: x} : __adaptStruct2(self,x);
};
if(1===arguments.length){
si = ads(structName);
structName = si.structName || si.name;
}else if(2===arguments.length){
si = ads(si);
si.name ??= structName;
}else{
si = ads(si);
}
structName ??= si.structName;
//console.warn("arguments =",JSON.stringify(arguments));
structName ??= opt.structName;
if( !structName ) toss("One of 'name' or 'structName' are required.");
if( si.adapt ){
Object.keys(si.adapt.struct||{}).forEach((k)=>{
__adaptStruct.call(StructBinderImpl, k, si.adapt.struct[k]);
});
Object.keys(si.adapt.set||{}).forEach((k)=>{
__adaptSet.call(StructBinderImpl, k, si.adapt.set[k]);
});
Object.keys(si.adapt.get||{}).forEach((k)=>{
__adaptGet.call(StructBinderImpl, k, si.adapt.get[k]);
});
}
if(!si.members && !si.sizeof){
si.sizeof = sigSize(si.signature);
}
const debugFlags = rop(SBF.__makeDebugFlags(StructBinder.debugFlags));
Object.defineProperties(StructCtor,{
debugFlags: debugFlags,
isA: rop((v)=>v instanceof StructCtor),
memberKey: __memberKeyProp,
memberKeys: __structMemberKeys,
methodInfoForKey: rop(function(mKey){
}),
structInfo: rop(structInfo),
//methodInfoForKey: rop(function(mKey){/*???*/}),
structInfo: rop(si),
structName: rop(structName)
});
StructCtor.prototype = new StructType(structName, structInfo, rop);
StructCtor.prototype = new StructType(structName, si, rop);
Object.defineProperties(StructCtor.prototype,{
debugFlags: debugFlags,
constructor: rop(StructCtor)
/*if we assign StructCtor.prototype and don't do
this then StructCtor!==instance.constructor!*/
this then StructCtor!==instance.constructor*/
});
Object.keys(structInfo.members).forEach(
(name)=>makeMemberWrapper(StructCtor, name, structInfo.members[name])
);
let lastMember = false;
let offset = 0;
//console.warn(structName,"si =",si);
si.offset ??= 0;
Object.keys(si.members || {}).forEach((k)=>{
// Sanity checks of sizeof/offset info...
let m = ads(si.members[k]);
if(!m.members && !m.sizeof){
/* ^^^^ fixme: we need to recursively collect all sizeofs
before updating that. */
m.sizeof = sigSize(m.signature);
if(!m.sizeof){
toss(sPropName(structName,k), "is missing a sizeof property.",m);
}
}
if( undefined===m.offset ){
m.offset = offset;
}
si.members[k] = m;
if(!lastMember || lastMember.offset < m.offset) lastMember = m;
makeMemberWrapper.call(self, StructCtor, k, m)
offset += m.sizeof;
//console.warn("offset",sPropName(structName,k),offset);
});
if( !lastMember ) toss("No member property descriptions found.");
if( !si.sizeof ) si.sizeof = offset;
if(si.sizeof===1){
(si.signature === 'c' || si.signature === 'C') ||
toss("Unexpected sizeof==1 member",
sPropName(structName,k),
"with signature",si.signature);
}else{
// sizes and offsets of size-1 members may be odd values, but
// others may not.
if(0!==(si.sizeof%4)){
console.warn("Invalid struct member description",si);
toss(structName,"sizeof is not aligned. sizeof="+si.sizeof);
}
if(0!==(si.offset%4)){
console.warn("Invalid struct member description",si);
toss(structName,"offset is not aligned. offset="+si.offset);
}
}
if( si.sizeof < offset ){
console.warn("Suspect struct description:",si,"offset =",offset);
toss("Mismatch in the calculated vs. the provided sizeof/offset info.",
"Expected sizeof",offset,"but got",si.sizeof,"for",si);
}
return StructCtor;
}/*StructBinderImpl*/;
const StructBinder = function StructBinder(structName, structInfo){
return (1==arguments.length)
? StructBinderImpl.call(StructBinder, structName)
: StructBinderImpl.call(StructBinder, structName, structInfo);
};
StructBinder.StructType = StructType;
StructBinder.config = config;
StructBinder.allocCString = __allocCString;
StructBinder.adaptGet = __adaptGet;
StructBinder.adaptSet = __adaptSet;
StructBinder.adaptStruct = __adaptStruct;
if(!StructBinder.debugFlags){
StructBinder.debugFlags = SBF.__makeDebugFlags(SBF.debugFlags);
}
+29 -34
View File
@@ -71,13 +71,13 @@ enum BuildDefFlags {
** only their JS file and patch their JS to use the WASM file from a
** canonical build which uses that same WASM file. Reusing X.wasm
** that way can only work for builds which are processed identically
** by Emscripten. For a given set of C flags (as opposed to
** by Emscripten. For a given set of C flags (as distinct from
** JS-influencing flags), all builds of X.js and Y.js will produce
** identical X.wasm and Y.wasm files. Their JS files may well
** differ, however.
*/
CP_JS = 1 << 30,
CP_WASM = 1 << 31,
CP_JS = 1 << 30, /* X.js or X.mjs, depending on F_ESM */
CP_WASM = 1 << 31, /* X,wasm */
CP_ALL = CP_JS | CP_WASM
};
@@ -94,11 +94,10 @@ enum BuildDefFlags {
** final build directory $(dir.dout).
**
** To keep parallel builds from stepping on each other, each distinct
** build goes into its own subdir $(dir.dout.BuildName)[^1], i.e.
** $(dir.dout)/BuildName. Builds which produce deliverables we'd like
** to keep/distribute copy their final results into the build dir
** $(dir.dout). See the notes for the CP_JS enum entry for more
** details on that.
** build goes into its own subdir $(dir.dout.$(BuildDef::zBaseName).
** Builds which produce deliverables we'd like to keep/distribute copy
** their final results into the build dir $(dir.dout). See the notes
** for the CP_JS enum entry for more details on that.
**
** The final result of each build is a pair of JS/WASM files, but
** getting there requires generation of several files, primarily as
@@ -116,9 +115,9 @@ enum BuildDefFlags {
**
** --extern-post-js = gets injected immediately after
** sqlite3InitModule(), in the global scope. In this step we replace
** sqlite3InitModule() with a slightly customized, the main purpose of
** which is to (A) give us (not Emscripten) control over the arguments
** it accepts and (B) to run the library bootstrap step.
** sqlite3InitModule() with a slightly customized one, the main
** purpose of which is to (A) give us (not Emscripten) control over
** the arguments it accepts and (B) to run the library bootstrap step.
**
** Then there's sqlite3-api.BuildName.js, which is the entire SQLite3
** JS API (generated from the list defined in $(sqlite3-api.jses)). It
@@ -126,9 +125,7 @@ enum BuildDefFlags {
**
** Each of those inputs has to be generated before passing them on to
** Emscripten so that any build-specific capabilities can get filtered
** in or out (using ./c-pp.c).
**
** [^1]: The legal BuildNames are in this file's BuildDef_map macro.
** in or out (using ./c-pp-lite.c).
*/
struct BuildDef {
/*
@@ -143,8 +140,8 @@ struct BuildDef {
**
** The convention for 32- vs 64-bit pairs is to give them similar
** emoji, e.g. a cookie for 32-bit and a donut or cake for 64.
** Alternately, the same emoji a "64" suffix, excep that that throws
** off the output alignment in parallel builds ;).
** Alternately, the same emoji a "64" suffix, except that that
** throws off the output alignment in parallel builds ;).
*/
const char *zEmo;
/*
@@ -161,7 +158,7 @@ struct BuildDef {
const char *zCmppD; /* Extra -D... flags for c-pp */
const char *zEmcc; /* Full flags for emcc. Normally NULL for default. */
const char *zEmccExtra; /* Extra flags for emcc */
const char *zDeps; /* Extra deps */
const char *zDeps; /* Extra make target deps */
const char *zEnv; /* emcc -sENVIRONMENT=... value */
/*
** Makefile code "ifeq (...)". If set, this build is enclosed in a
@@ -196,9 +193,8 @@ typedef struct BuildDef BuildDef;
** The set of WASM builds for the library (as opposed to the apps
** (fiddle, speedtest1)). Their order in BuildDefs_map is mostly
** insignificant, but some makefile vars used by some builds are set
** up by prior builds. Because of that, the (sqlite3, vanilla),
** (sqlite3, esm), and (sqlite3, bundler-friendly) builds should be
** defined first (in that order).
** up by prior builds. Because of that, the vanilla, esm, and
** bundler-friendly builds should be defined first (in that order).
*/
struct BuildDefs {
#define E(N) BuildDef N;
@@ -284,7 +280,7 @@ const BuildDefs oBuildDefs = {
" -DSQLITE_SPEEDTEST1_WASM"
" $(SQLITE_OPT)"
" -USQLITE_WASM_BARE_BONES"
" -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c)"
" -USQLITE_C -DSQLITE_C=$(sqlite3.c)"
" $(speedtest1.exit-runtime0)"
" $(speedtest1.c.in)"
" -lm",
@@ -312,7 +308,7 @@ const BuildDefs oBuildDefs = {
" -DSQLITE_SPEEDTEST1_WASM"
" $(SQLITE_OPT)"
" -USQLITE_WASM_BARE_BONES"
" -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c)"
" -USQLITE_C -DSQLITE_C=$(sqlite3.c)"
" $(speedtest1.exit-runtime0)"
" $(speedtest1.c.in)"
" -lm",
@@ -346,7 +342,6 @@ const BuildDefs oBuildDefs = {
.zDeps = 0,
.zIfCond = 0,
.flags = CP_JS | F_BUNDLER_FRIENDLY | F_ESM
//| F_NOT_IN_ALL
},
/* 64-bit bundler-friendly. */
@@ -371,7 +366,7 @@ const BuildDefs oBuildDefs = {
.node = {
.zEmo = "🍟",
.zBaseName = "sqlite3-node",
.zDotWasm = 0,
.zDotWasm = "sqlite3",
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
.zEmcc = 0,
.zEmccExtra = 0,
@@ -382,21 +377,21 @@ const BuildDefs oBuildDefs = {
** node. */,
.zDeps = 0,
.zIfCond = 0,
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS
.flags = CP_JS | F_UNSUPPORTED | F_ESM | F_NODEJS
},
/* 64-bit node. */
.node64 = {
.zEmo = "🍔",
.zBaseName = "sqlite3-node-64bit",
.zDotWasm = 0,
.zDotWasm = "sqlite3-64bit",
.zCmppD = "-Dtarget:node $(c-pp.D.bundler)",
.zEmcc = 0,
.zEmccExtra = 0,
.zEnv = "node",
.zDeps = 0,
.zIfCond = 0,
.flags = CP_ALL | F_UNSUPPORTED | F_NODEJS | F_64BIT
.flags = CP_JS | F_UNSUPPORTED | F_ESM | F_NODEJS | F_64BIT
},
/* Entirely unsupported. */
@@ -638,7 +633,7 @@ static void mk_pre_post(char const *zBuildName, BuildDef const * pB){
pB->zDotWasm);
}
ps("");
pf("\t@$(call b.c-pp.shcmd,"
pf("\t@$(call b.mkdir@); $(call b.c-pp.shcmd,"
"%s,"
"$(pre-js.in.js),"
"$(pre-js.%s.js),"
@@ -777,13 +772,14 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
zBuildName, zBuildName, zBaseName);
pf("dir.dout.%s ?= $(dir.dout)/%s\n", zBuildName, zBuildName);
pf("out.%s.base ?= $(dir.dout.%s)/%s\n",
zBuildName, zBuildName, zBaseName);
pf("c-pp.D.%s ?= %s\n", zBuildName, pB->zCmppD ? pB->zCmppD : "");
if( pB->flags & F_64BIT ){
pf("c-pp.D.%s += $(c-pp.D.64bit)\n", zBuildName);
}
if( pB->flags & F_UNSUPPORTED ){
pf("c-pp.D.%s += -Dunsupported-build\n", zBuildName);
}
pf("emcc.environment.%s ?= %s\n", zBuildName,
pB->zEnv ? pB->zEnv : oBuildDefs.vanilla.zEnv);
@@ -914,10 +910,9 @@ static void mk_lib_mode(const char *zBuildName, const BuildDef * pB){
pf("\n%dbit: $(out.%s.js)\n"
"$(out.%s.wasm): $(out.%s.js)\n"
"b-%s: $(out.%s.js) $(out.%s.wasm)\n",
"b-%s: $(out.%s.wasm)\n",
(F_64BIT & pB->flags) ? 64 : 32, zBuildName,
zBuildName, zBuildName,
zBuildName, zBuildName, zBuildName);
zBuildName, zBuildName, zBuildName, zBuildName);
if( CP_JS & pB->flags ){
pf("$(dir.dout)/%s%s: $(out.%s.js)\n",
@@ -992,7 +987,7 @@ static void mk_fiddle(void){
zBuildName, zBuildName);
emit_compile_start(zBuildName);
pf("\t$(b.cmd@)$(bin.emcc) -o $@"
" $(emcc.flags.%s)" /* set in fiddle.make */
" $(emcc.flags.%s)" /* set in GNUmakefile */
" $(pre-post.%s.flags)"
" $(fiddle.c.in)"
"\n",
+13 -5
View File
@@ -12,11 +12,19 @@
</head>
<body>
<h1 id='color-target'>sqlite3 tester #1: Worker thread (@bitness@-bit WASM)</h1>
<div>Variants:
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
<div>Variants (32-bit):
conventional UI thread:
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
conventional worker:
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
ESM in UI thread:
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
ESM worker:</a>
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
</div>
<div class='input-wrapper'>
<input type='checkbox' id='cb-log-reverse'>
+13 -5
View File
@@ -11,11 +11,19 @@
<style></style>
</head>
<body><h1 id='color-target'></h1>
<div>Variants:
<a href='tester1.html' target='tester1.html'>conventional UI thread</a>,
<a href='tester1-worker.html' target='tester1-worker.html'>conventional worker</a>,
<a href='tester1-esm.html' target='tester1-esm.html'>ESM in UI thread</a>,
<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>ESM worker</a>
<div>Variants (32-bit):
conventional UI thread:
(<a href='tester1.html' target='tester1.html'>32-bit</a>,
<a href='tester1-64bit.html' target='tester1-64bit.html'>64-bit</a>),
conventional worker:
(<a href='tester1-worker.html' target='tester1-worker.html'>32-bit</a>,
<a href='tester1-worker-64bit.html' target='tester1-worker-64bit.html'>64-bit</a>),
ESM in UI thread:
(<a href='tester1-esm.html' target='tester1-esm.html'>32-bit</a>,
<a href='tester1-esm-64bit.html' target='tester1-esm-64bit.html'>64-bit</a>),
ESM worker:</a>
(<a href='tester1-worker.html?esm' target='tester1-worker.html?esm'>32-bit</a>
<a href='tester1-worker-64bit.html?esm' target='tester1-worker-64bit.html?esm'>64-bit</a>)
</div>
<div class='input-wrapper'>
<input type='checkbox' id='cb-log-reverse'>
+149 -231
View File
@@ -369,6 +369,88 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
clearOnInit: true,
initialCapacity: 6
};
//#if enable-see
/**
Code consolidator for SEE sanity checks for various VFSes. ctor
is the VFS's oo1.DB-type constructor. ctorOptFunc(bool) is a
function which must return a constructor args object for ctor. It
is passed true if the db needs to be cleaned up/unlinked before
opening it (OPFS) and false if not (how that is done is
VFS-dependent). dbUnlink is a function which is expected to
unlink() the db file if the ctorOpfFunc does not do so when
passed true (kvvfs).
This function initializes the db described by ctorOptFunc(...),
writes some secret info into it, and re-opens it twice to
confirmi that it can be read with an SEE key and cannot be read
without one.
*/
T.seeBaseCheck = function(ctor, ctorOptFunc, dbUnlink){
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
try {
if (initDb) {
const ctoropt = ctorOptFunc(initDb);
initDb = false;
db = new ctor({
...ctoropt,
[keyKey]: key
});
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
db = null;
// Ensure that it's actually encrypted...
let err;
try {
db = new ctor(ctorOptFunc(false));
T.assert(db, 'db opened') /* opening is fine, but... */;
db.exec("select 1 from sqlite_schema");
console.warn("(should not be reached) sessionStorage =", sessionStorage);
} catch (e) {
err = e;
} finally {
db.close()
db = null;
}
T.assert(err, "Expecting an exception")
.assert(capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
db = new ctor({
...ctorOptFunc(false),
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
};
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
dbUnlink();
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
dbUnlink();
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
dbUnlink();
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
dbUnlink();
},
//#endif enable-see
////////////////////////////////////////////////////////////////////////
// End of infrastructure setup. Now define the tests...
////////////////////////////////////////////////////////////////////////
@@ -945,7 +1027,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
let ptr = k1.pointer;
k1.dispose();
T.assert(undefined === k1.pointer).
mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
mustThrowMatching(()=>{k1.$pP=1}, /disposed struct instance/);
}finally{
k1.dispose();
k2.dispose();
@@ -1549,6 +1631,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
T.assert(blob instanceof Uint8Array).
assert(0x68===blob[0] && 0x69===blob[1]);
blob = null;
blob = db.selectValue("select ?1", new Uint8Array([97,0,98,0,99]),
sqlite3.capi.SQLITE_TEXT);
T.assert("a\0b\0c"===blob, "Something is amiss with embedded NULs");
let counter = 0, colNames = [];
list.length = 0;
db.exec(new TextEncoder('utf-8').encode("SELECT a a, b b FROM t"),{
@@ -2836,71 +2921,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
predicate: ()=>(isUIThread()
|| "Only available in main thread."),
test: function(sqlite3){
this.kvvfsUnlink();
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
const ctoropt = {
filename: this.kvvfsDbFile
//vfs: 'kvvfs'
//,flags: 'ct'
};
try {
if (initDb) {
initDb = false;
db = new this.JDb({
...ctoropt,
[keyKey]: key
});
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
// Ensure that it's actually encrypted...
let err;
try {
db = new this.JDb(ctoropt);
T.assert(db, 'db opened') /* opening is fine, but... */;
db.exec("select 1 from sqlite_schema");
console.warn("(should not be reached) sessionStorage =", sessionStorage);
} catch (e) {
err = e;
} finally {
db.close()
}
T.assert(err, "Expecting an exception")
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
//console.debug('tryKey()',arguments);
db = new sqlite3.oo1.DB({
...ctoropt,
vfs: 'kvvfs',
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
}.bind(this);
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
this.kvvfsUnlink();
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
this.kvvfsUnlink();
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
this.kvvfsUnlink();
T.seeBaseCheck(sqlite3.oo1.JsStorageDb, (isInit)=>{
return {filename: "session"};
}, ()=>this.kvvfsUnlink());
}
})/*kvvfs with SEE*/
//#endif enable-see
@@ -3315,71 +3338,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.t({
name: 'OPFS with SEE encryption',
test: function(sqlite3){
const dbFile = 'file:///sqlite3-see.edb';
const dbCtor = sqlite3.oo1.OpfsDb;
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
const ctoropt = {
filename: dbFile,
flags: 'c'
};
try {
if (initDb) {
initDb = false;
const opt = {
...ctoropt,
[keyKey]: key
};
opt.filename += '?delete-before-open=1';
db = new dbCtor(opt);
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
// Ensure that it's actually encrypted...
let err;
try {
db = new dbCtor(ctoropt);
T.assert(db, 'db opened') /* opening is fine, but... */;
const rv = db.exec({
sql:"select count(*) from sqlite_schema",
returnValue: 'resultRows'
});
console.warn("(should not be reached) rv =",rv);
} catch (e) {
err = e;
} finally {
db.close()
}
T.assert(err, "Expecting an exception")
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
db = new dbCtor({
...ctoropt,
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
};
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
T.seeBaseCheck(
sqlite3.oo1.OpfsDb,
function(isInit){
const opt = {filename: 'file:///sqlite3-see.edb'};
if( isInit ) opt.filename += '?delete-before-open=1';
return opt;
},
()=>{});
}
})/*OPFS with SEE*/
//#endif enable-see
@@ -3584,69 +3550,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
let poolUtil;
const P1 = await inst(poolConfig).then(u=>poolUtil = u).catch(catcher);
const dbFile = '/sqlite3-see.edb';
const dbCtor = poolUtil.OpfsSAHPoolDb;
const hexFoo = new Uint8Array([0x66,0x6f,0x6f]/*=="foo"*/);
let initDb = true;
const tryKey = function(keyKey, key, expectCount){
let db;
//console.debug('tryKey()',arguments);
const ctoropt = {
filename: dbFile,
flags: 'c'
};
try {
if (initDb) {
initDb = false;
poolUtil.unlink(dbFile);
db = new dbCtor({
...ctoropt,
[keyKey]: key
});
db.exec([
"drop table if exists t;",
"create table t(a);"
]);
db.close();
// Ensure that it's actually encrypted...
let err;
try {
db = new dbCtor(ctoropt);
T.assert(db, 'db opened') /* opening is fine, but... */;
const rv = db.exec({
sql:"select count(*) from sqlite_schema",
returnValue: 'resultRows'
});
console.warn("(should not be reached) rv =",rv);
} catch (e) {
err = e;
} finally {
db.close()
}
T.assert(err, "Expecting an exception")
.assert(sqlite3.capi.SQLITE_NOTADB == err.resultCode,
"Expecting NOTADB");
}/*initDb*/
db = new dbCtor({
...ctoropt,
[keyKey]: key
});
db.exec("insert into t(a) values (1),(2)");
T.assert(expectCount === db.selectValue('select sum(a) from t'));
} finally {
if (db) db.close();
}
};
tryKey('textkey', 'foo', 3);
T.assert( !initDb );
tryKey('textkey', 'foo', 6);
initDb = true;
tryKey('key', 'foo', 3);
T.assert( !initDb );
tryKey('key', hexFoo, 6);
initDb = true;
tryKey('hexkey', hexFoo, 3);
T.assert( !initDb );
tryKey('hexkey', hexFoo, 6);
T.seeBaseCheck(
poolUtil.OpfsSAHPoolDb,
(isInit)=>{return {filename: dbFile}},
()=>poolUtil.unlink(dbFile)
);
poolUtil.removeVfs();
}
})/*opfs-sahpool with SEE*/
@@ -3715,44 +3623,54 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.t("Misc. stmt_...", function(sqlite3){
const db = new sqlite3.oo1.DB();
db.exec("create table t(a doggiebiscuits); insert into t(a) values(123)");
const stmt = db.prepare("select a, a+1 from t");
T.assert( stmt.isReadOnly() )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
let n = 0;
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
++n;
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
"Because stmt is busy" )
.assert( capi.sqlite3_stmt_busy(stmt) )
.assert( stmt.isBusy() )
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
.assert( true===stmt.isReadOnly() );
const sv = capi.sqlite3_column_value(stmt, 0);
T.assert( 123===capi.sqlite3_value_int(sv) )
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
let stmt;
try{
stmt = db.prepare("select a, a+1 from t");
T.assert( stmt.isReadOnly() )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 1) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 2) )
.assert( 0!==capi.sqlite3_stmt_isexplain(stmt) )
.assert( 0===capi.sqlite3_stmt_explain(stmt, 0) )
.assert( 0===capi.sqlite3_stmt_isexplain(stmt) );
let n = 0;
while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){
++n;
T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1),
"Because stmt is busy" )
.assert( capi.sqlite3_stmt_busy(stmt) )
.assert( stmt.isBusy() )
.assert( 0!==capi.sqlite3_stmt_readonly(stmt) )
.assert( true===stmt.isReadOnly() );
const sv = capi.sqlite3_column_value(stmt, 0);
T.assert( 123===capi.sqlite3_value_int(sv) )
.assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) )
.assert( null===capi.sqlite3_column_decltype(stmt,1) );
}
T.assert( 1===n )
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
.assert( !stmt.isBusy() );
if( wasm.exports.sqlite3_column_origin_name ){
log("Column metadata APIs enabled");
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
}else{
log("Column metadata APIs not enabled");
} // column metadata APIs
stmt.finalize();
stmt = null;
stmt = db.prepare("select ?1").bind(new Uint8Array([97,0,98,0,99]));
stmt.step();
const sv = capi.sqlite3_column_value(stmt,0);
T.assert("a\0b\0c"===capi.sqlite3_value_text(sv),
"Expecting NULs to have survived.");
}finally{
if(stmt) stmt.finalize();
db.close();
}
T.assert( 1===n )
.assert( 0===capi.sqlite3_stmt_busy(stmt) )
.assert( !stmt.isBusy() );
if( wasm.exports.sqlite3_column_origin_name ){
log("Column metadata APIs enabled");
T.assert( "t" === capi.sqlite3_column_table_name(stmt, 0))
.assert("a" === capi.sqlite3_column_origin_name(stmt, 0))
.assert("main" === capi.sqlite3_column_database_name(stmt, 0))
}else{
log("Column metadata APIs not enabled");
} // column metadata APIs
stmt.finalize();
db.close();
})
////////////////////////////////////////////////////////////////////
-19
View File
@@ -952,25 +952,6 @@ FUZZDATA = \
#
TESTOPTS = --verbose=file --output=test-out.txt
#
# Extra compiler options for various shell tools
#
# Note that some of these will only apply when embedding sqlite3.c
# into the shell, as these flags are not otherwise passed on to the
# library.
SHELL_OPT += -DSQLITE_DQS=0
SHELL_OPT += -DSQLITE_ENABLE_FTS4
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_PERCENTILE
SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1
FUZZERSHELL_OPT =
FUZZCHECK_OPT += -I$(TOP)/test
FUZZCHECK_OPT += -I$(TOP)/ext/recover
+58 -62
View File
@@ -1,14 +1,14 @@
C Version\s3.51.1
D 2025-11-28T17:28:25.933
C Pervent\sthe\sparser\sstack\sfrom\sgrowing\sto\sbe\slarger\sthan\s100\splus\sfour\stimes\nthe\sSQLITE_LIMIT_EXPR_DEPTH\ssetting.
D 2025-11-18T02:24:46.688
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
F Makefile.msc 8dd676302f3165984c046f81af14b6676a334418fa30255efaf439f8033042fa
F Makefile.msc 523bab2f6569e912a0aaf2d13e0b3f9bcb36d52310b236d950b354068c9de3f3
F README.md dae499194b75deed76a13a4a83c82493f2530331882d7dfe5754d63287d3f8f7
F VERSION a3971cc92c03ff4c250d95d1ecf61e2433152c21926d8a7dd429b39218a6e4c7
F VERSION 74672bfd4c7826c0fc6f84762488a707c52e7d2d94af42ccb0edcc6c74311c41
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -17,7 +17,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531
F auto.def 44a0d1bf09d78355fc88251ccbf8e64e6341fd89c11de68a01c3645e53a2bade
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
F autoconf/Makefile.in 118aa2c4d49173672d065fdda19eb8a28642e2c684212d7a626d6db5e6762521
F autoconf/Makefile.in 306f500fce8cae9e1af9459f1ac7fe89ce46999594ef3fdc62dc9d7d651fb091
F autoconf/Makefile.msc 803aa9e23b6a764751f6a91d0673620eefa46729fb80faf51391120e1d752966
F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136
F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807
@@ -47,7 +47,7 @@ F autosetup/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1
F autosetup/jimsh0.c a57c16e65dcffc9c76e496757cb3f7fb47e01ecbd1631a0a5e01751fc856f049
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
F autosetup/proj.tcl 6fc14ef82b19b77a95788ffbcfad7989b4e3cb4ce96a21dcb5cf7312f362fba9
F autosetup/sqlite-config.tcl 5d779fce20c11fde3fe99d157dcd5b5569d729b301141b8dfb8d5aacf9d48cba
F autosetup/sqlite-config.tcl 1fd7c55394051fbfba2fb9fa9192c027ee7d74612dbf772b06e27feb9f1de5df
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
F autosetup/teaish/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca
F autosetup/teaish/core.tcl e014dd95900c7f9a34e8e0f460f47e94841059827bce8b4c49668b0c7ae3f1a0
@@ -60,7 +60,7 @@ F doc/compile-for-unix.md c9dce1ddd4bf0d25efccc5c63eb047e78c01ce06a6ff29c73e0a8a
F doc/compile-for-windows.md f9e74d74da88f384edd5809f825035e071608f00f7f39c0e448df7b3982f979c
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
F doc/jsonb.md acd77fc3a709f51242655ad7803510c886aa8304202fa9cf2abc5f5c4e9d7ae5
F doc/lemon.html 89ea833a6f71773ab1a9063fbb7fb9b32147bc0b1057b53ecab94a3b30c0aef5
F doc/lemon.html 0e4b854b5ca0cf3600fec4da454197f651e8a0d411a90653703e75474486ad31
F doc/pager-invariants.txt 83aa3a4724b2d7970cc3f3461f0295c46d4fc19a835a5781cbb35cb52feb0577
F doc/tcl-extension-testing.md b88861804fc1eaf83249f8e206334189b61e150c360e1b80d0dcf91af82354f5
F doc/testrunner.md 5ee928637e03f136a25fef852c5ed975932e31927bd9b05a574424ae18c31019
@@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d
F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8
F ext/fts5/fts5_expr.c b8c32da1127bafaf10d6b4768b0dcb92285798524bed2d87a8686f99a8e8d259
F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0
F ext/fts5/fts5_index.c 5e82963a6691ae519df1e018cc7971272a3da1fd47daca5029af0e9ce24f1a8b
F ext/fts5/fts5_index.c 8dbda33a9830764167d7697f1c9980c8a6ee74f5decb28206b963222583b8cdd
F ext/fts5/fts5_main.c 42025174a556257287071e90516d3ab8115daf1dd525a301883544469a260014
F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2
F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329
@@ -122,7 +122,7 @@ F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a
F ext/fts5/fts5_tokenize.c 49aea8cc400a690a6c4f83c4cedc67f4f8830c6789c4ee343404f62bcaebca7b
F ext/fts5/fts5_unicode2.c 536a6dae41d16edadd6a6b58c56e2ebbb133f0dfe757562a2edbcdc9b8362e50
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
F ext/fts5/fts5_vocab.c 23e263ad94ac357cfffd19bd7e001c3f15c4420fb10fa35b5993142127e780e6
F ext/fts5/fts5_vocab.c ff0441c4ea165081e8152dec6d29056faa0cdc281a9f218a00e3d7aacc1958bc
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
F ext/fts5/test/fts5_common.tcl c5aa7cf7148b6dcffb5b61520ae18212baf169936af734ab265143f59db328fe
@@ -162,7 +162,7 @@ F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b
F ext/fts5/test/fts5contentless5.test 38cd0392c730dc7090c550321ce3c24ba4c392bc97308b51a4180e9959dca7b5
F ext/fts5/test/fts5corrupt.test 237fce1c3261bb3a5bec333b0f0dbf5b105ec32627ef14cccbda3cfe13833193
F ext/fts5/test/fts5corrupt2.test 4a03a158c2cb617c9f76d26b35c1ef2534124bc0bbddcea38dfd5b170ebea27b
F ext/fts5/test/fts5corrupt3.test e489b51b6c4ded2a808e0f78bdbe126f6d369de41a59ac2717878e37fc3db0e8
F ext/fts5/test/fts5corrupt3.test 43d6a836892d79ab738ab89b3b6f4ae46c07ee966193e4b357bbb14e7f81d5da
F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733
F ext/fts5/test/fts5corrupt5.test 73985d4fe6d8f0d5d5c7bcf79ae7c6522c376cd6ad710a0ff2f26e0c2e222abe
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
@@ -269,7 +269,7 @@ F ext/fts5/test/fts5update.test b8affd796e45c94a4d19ad5c26606ea06065a0f162a9562d
F ext/fts5/test/fts5update2.test c5baa76799ac605ebb8e5e21035db2014b396cef25c903eb96ba39b1d6f9f046
F ext/fts5/test/fts5version.test 44ab35566267b7618c090443de2d9ad84f633df5d20bf72e9bad199ae5fced84
F ext/fts5/test/fts5vocab.test 2a2bdb60d0998fa3124d541b6d30b019504918dc43a6584645b63a24be72f992
F ext/fts5/test/fts5vocab2.test 4265137a3747b27deb1e2e2bde5654120c6de72bfed3238e67806d85af60fc4c
F ext/fts5/test/fts5vocab2.test bbba149c254375d00055930c1a501c9a51e80b0d20bf7b98f3e9fa3b03786373
F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85
F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
@@ -288,10 +288,10 @@ F ext/intck/sqlite3intck.c b1c8a86f90fc00741d13314db9c58f7e2f92d1d19c5ad1c6904ec
F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
F ext/intck/test_intck.c 4f9eaadaedccb9df1d26ba41116a0a8e5b0c5556dc3098c8ff68633adcccdea8
F ext/jni/GNUmakefile 8a94e3a1953b88cf117fb2a5380480feada8b4f5316f02572cab425030a720b4
F ext/jni/README.md e3fbd47c774683539b7fdc95a667eb9cd6e64d8510f3ee327e7fa0c61c8aa787
F ext/jni/README.md 1479c83dbe26125264a060ee6873531795a7082dbc0d43c4067683371331559f
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
F ext/jni/src/c/sqlite3-jni.c 3d84a0176af779737ae977ba1c90d2ffe2537b8299c5d9f6552620493f12ac4b
F ext/jni/src/c/sqlite3-jni.h ac180ba9b21978727006c790d3006a95a2402a4c3ec7a0def92707ed89b79945
F ext/jni/src/c/sqlite3-jni.c 6ccc50b0e98b8ef8fd6a8b837223e1c8ebb92bfe6b976128cc757c26257d994a
F ext/jni/src/c/sqlite3-jni.h df43024cced914c49485633d0f90168689e70577b3b17b0ecbdaf16e4a417bff
F ext/jni/src/org/sqlite/jni/annotation/Experimental.java 8603498634e41d0f7c70f661f64e05df64376562ea8f126829fd1e0cdd47e82b
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java be6cc3e8e114485822331630097cc0f816377e8503af2fc02f9305ff2b353917
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 56e3dee1f3f703a545dfdeddc1c3d64d1581172b1ad01ffcae95c18547fafd90
@@ -301,7 +301,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0e28a0df51368c7127e505f
F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a
F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759
F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca
F ext/jni/src/org/sqlite/jni/capi/CApi.java 3d275f5f4fbdbe4fff15f4d42cf5ff559f9a4897e7373fa99f3b1dc9cf7f849c
F ext/jni/src/org/sqlite/jni/capi/CApi.java a9701cbe736b8bef5bc72ae465be0250e137f67bdb5a3ab62497972b6f51572d
F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 1b3baf5b772f266e8baf8f35f0ddc5bd87fc8c4927ec69115c46fd6fba6701c3
F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab
@@ -319,7 +319,7 @@ F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 0d1e9afc9ff8a2adb94a155b72385
F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 3c0babc067d8560627a9ed1b07979f9d4393464e2282c2fca4832052e982c7bc
F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615
F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java 9133bb7685901d2edf07801191284975e33b5583ce09dce1c05202ff91e7bb99
F ext/jni/src/org/sqlite/jni/capi/Tester1.java 4c3d16fdf6e979f839b2ecdb14d0a0c04bd3d0e41500fc9e8110b588883b140b
F ext/jni/src/org/sqlite/jni/capi/Tester1.java 378d142435d220b20b7ce7343c62a03e853bb8c51e80447ee0f8ac5c37362d9a
F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723
F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56
F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 2ce069f3e007fdbbe1f4e507a5a407fc9679da31a0aa40985e6317ed4d5ec7b5
@@ -346,7 +346,7 @@ F ext/jni/src/org/sqlite/jni/test-script-interpreter.md d7987b432870d23f7c72a780
F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483
F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 326ffba29aab836a6ea189703c3d7fb573305fd93da2d14b0f9e9dcf314c8290
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java e920f7a031e04975579240d4a07ac5e4a9d0f8de31b0aa7a4be753c98ae596c9
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java c82bc00c1988f86246a89f721d3c41f0d952f33f934aa6677ec87f7ca42519a0
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java ce8aef867e06a21685658eb0173768c355e9e1e2dfdc75f382643fa62c7ee779
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 08f92d52be2cec28a7b4555479cc54b7ebeeb94985256144eeb727154ec3f85b
F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java a84e90c43724a69c2ecebd601bc8e5139f869b7d08cb705c77ef757dacdd0593
@@ -372,7 +372,7 @@ F ext/misc/dbdump.c 678f1b9ae2317b4473f65d03132a2482c3f4b08920799ed80feedd2941a0
F ext/misc/decimal.c d4883de142f6dcd36eda23da40b55e2b51374e7b01eb54a7173940191389fc5e
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b
F ext/misc/fileio.c d4918ff3f59a26c447347b40ac5e5c41aef697dfa24ebb2ef61ebad3c32261f0
F ext/misc/fileio.c 61af623160c073b605b4ff1f67d278c4c348956efa08f6201756577c7a050d17
F ext/misc/fossildelta.c 2fc2dd4f34f478df674887db62586b1071c4cd3c9e73ee40f9ee669670e482d1
F ext/misc/fuzzer.c 6b231352815304ba60d8e9ec2ee73d4918e74d9b76bda8940ba2b64e8777515e
F ext/misc/ieee754.c 176c061c94857b543313959289cb60cf777c999fd002f82b53d194b95e9f347a
@@ -575,8 +575,7 @@ F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009e
F ext/session/sqlite3session.c b3de195ce668cace9b324599bf6255a70290cbfb5451e826e946f3aee6e64c54
F ext/session/sqlite3session.h 7404723606074fcb2afdc6b72c206072cdb2b7d8ba097ca1559174a80bc26f7a
F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
F ext/wasm/GNUmakefile 3dc01e673c456d3b752674c9407276e8fef35dec1d304b3cc1de362f019b2a09
F ext/wasm/GNUmakefile 01f5e1bc688911b0c0accb0b152dccb19818cb301a90ba9772e3b329a7f625b0
F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a
F ext/wasm/README.md 2e87804e12c98f1d194b7a06162a88441d33bb443efcfe00dc6565a780d2f259
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
@@ -584,35 +583,31 @@ F ext/wasm/SQLTester/SQLTester.mjs 6b3c52ed36a5573ca4883176f326332a8d4c0cecf5efd
F ext/wasm/SQLTester/SQLTester.run.mjs 57f2adb33f43f2784abbf8026c1bfd049d8013af1998e7dcb8b50c89ffc332e0
F ext/wasm/SQLTester/index.html 64f3435084c7d6139b08d1f2a713828a73f68de2ae6a3112cbb5980d991ba06f
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core ef34398a903d0a2425fbbfbd4ed2cd596daea55b8515e2617c8dc7ad7c0767dd
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras 9eae68943ce91ab145892b31370819c2103525240eb72e0fce53c498b8d8275a
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md f4c0d67caaee21a77b8938c30b5f79667bfc9d0c95d01b51df77ea35ee773884
F ext/wasm/api/extern-post-js.c-pp.js 205f55aacfc62c580985db5c790300779de3876a76a5c7e1bfb13e71c8b4506b
F ext/wasm/api/EXPORTED_FUNCTIONS.c-pp d609c22bc05e25991bdd2eeed4497485a3756446158b2794471426e5e3517056
F ext/wasm/api/README.md aae128e14711dafac29e7b645ff1b6be42305b73f74b1303d8401351f8448631
F ext/wasm/api/extern-post-js.c-pp.js 4b310c9891886e7c1ea4e2419966ff45dfeda825b897fdaa4119332509f7e3d1
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
F ext/wasm/api/post-js-footer.js 5bd7170b5e8ce7b62102702bbcf47ef7b3b49cd56ed40c043fd990aa715b74ee
F ext/wasm/api/post-js-header.js 79d078aec33d93b640a19c574b504d88bb2446432f38e2fbb3bb8e36da436e70
F ext/wasm/api/pre-js.c-pp.js a876c6399dff29b6fe9e434036beb89889164cc872334e184291723ecc7cb072
F ext/wasm/api/sqlite3-api-cleanup.js a3d6b9e449aefbb8bba283c2ba9477e2333a0eeb94a7a26b5bf952736f65a6dd
F ext/wasm/api/sqlite3-api-glue.c-pp.js d2b8263b3ce0cefc6c5a68d0a4d448a9770eda4bf9d9ded9d7eb0198e4ce4da1
F ext/wasm/api/post-js-footer.js a50c1a2c4d008aede7b2aa1f18891a7ee71437c2f415b8aeb3db237ddce2935b
F ext/wasm/api/post-js-header.js d24bd0d065f3489c8b78ddf3ead6321e5d047187a162cd503c41700e03dd1f06
F ext/wasm/api/pre-js.c-pp.js ad2546290e0c8ce5ca2081bff6e85cc25eeb904a3303921f1184290a7ff1b32f
F ext/wasm/api/sqlite3-api-glue.c-pp.js 79a54b54ca6324d28e31e19b56bbaebb7d2cc4b3079066e7e901333fa5047c53
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 31dbfd470c91ffd96d77399b749bab6b69e3ba9074188833f97ac13f087cf07b
F ext/wasm/api/sqlite3-api-prologue.js 307583ff39a978c897c4ef4ce53fe231dce5c73dc84785969c81c1ab5960a293
F ext/wasm/api/sqlite3-api-prologue.js a7cab3e8f78d5a93d7173657677fef18265f48d4e0b1e1755740f734a69cae6d
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667430f9d45167569633ffc7567938
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 26cb41d5a62f46a106b6371eb00fef02de3cdbfaa51338ba087a45f53028e0d0
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 418c33fe284739564daab3c7a7a88882fdd3c99137497900f98eddec1e409af5
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js aa330fa0e8ef35cbd92eb0d52e05fbaa07e61540c5cb164e693c82428ce1d763
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86
F ext/wasm/api/sqlite3-wasm.c dd7fc1d535281f0d5d2732bb1b662d1d403a762f07b63c2ea5663053377b2804
F ext/wasm/api/sqlite3-wasm.c 03451f8335f4ba8ea9a79dfc170560b1ee5376de64ff49c1a114274ccf50ab3d
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bda1c75bd674a92a0e27cc2f3d46dbbf21e422413f8046814515a0bd7409328a
F ext/wasm/api/sqlite3-worker1.c-pp.js 802d69ead8c38dc1be52c83afbfc77e757da8a91a2e159e7ed3ecda8b8dba2e7
F ext/wasm/c-pp-lite.c 8fa0148e73782a86274db688c4730e2962cd675af329490493adddaf3322f16f
F ext/wasm/c-pp-lite.c 943be1a36774d58385dca32de36fc18d4f432fe79f7aa35e6c85dd6a6b825bd0
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
F ext/wasm/common/whwasmutil.js 0d539324097fc83b953e9844267359ba0fd02286caa784ea2f597ced279ea640
F ext/wasm/common/whwasmutil.js 804409dec98458f732b23e6e86788934ac6dec002107435cc4055355585d1c15
F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
@@ -629,10 +624,10 @@ F ext/wasm/fiddle/fiddle.js 84fd75967e0af8b69d3dd849818342227d0f81d13db92e0dcbc6
F ext/wasm/fiddle/index.html a27b8127ef9ecf19612da93b2a6a73bdb3777b5c56b5450bb7200a94bc108ff9
F ext/wasm/index-dist.html db23748044e286773f2768eec287669501703b5d5f72755e8db73607dc54d290
F ext/wasm/index.html 54e27db740695ab2cb296e02d42c4c66b3f11b65797340d19fa6590f5b287da1
F ext/wasm/jaccwabyt/jaccwabyt.js bbac67bc7a79dca34afe6215fd16b27768d84e22273507206f888c117e2ede7d
F ext/wasm/jaccwabyt/jaccwabyt.js 1e734c624205cdf621f322972dfb0fc8013d573a5882f57492a6830e5ec23e17
F ext/wasm/jaccwabyt/jaccwabyt.md 167fc0b624c9bc2c477846e336de9403842d81b1a24fc4d3b24317cb9eba734f
F ext/wasm/mkdist.sh 64d53f469c823ed311f6696f69cec9093f745e467334b34f5ceabdf9de3c5b28 x
F ext/wasm/mkwasmbuilds.c 1b53c4d2a1350c19a96a8cdfbda6a39baea9d2142bfe0cbef0ccb0e898787f47
F ext/wasm/mkwasmbuilds.c ef42e404236dd98cedb6ecea47b6d2474e3c593633ce6d992d316289dfc442b6
F ext/wasm/module-symbols.html e54f42112e0aac2a31f850ab33e7f2630a2ea4f63496f484a12469a2501e07e2
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
@@ -646,9 +641,9 @@ F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d826
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.c-pp.html 883881eeac14eeeecc8ff22acf9fe0f18a97cacb48be08ebb0bae891ceded584
F ext/wasm/tester1.c-pp.html 949920126dcf477925d8d540093d9cc374d3ab4c4ddee920c1dcadcf37917306
F ext/wasm/tester1.c-pp.js 2b014884dadf28928fabcb688746ca87145673eef75e154486505a266203fc15
F ext/wasm/tester1-worker.c-pp.html 0e432ec2c0d99cd470484337066e8d27e7aee4641d97115338f7d962bf7b081a
F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb
F ext/wasm/tester1.c-pp.js 2c255093205a0dac9dae7475030665c2c9d6dccc857de68ee7daf49aa82e6de8
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -658,7 +653,7 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca
F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk 00dd631c66c1f7922b2d691631163899eff1c3d1da780ff37a62f8d997b368e1
F main.mk 29078d11f7545a8fae4347305b164bb4e777b801da16baeb48214014a8d63a06
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -675,7 +670,7 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
F src/btree.c cb5b8ceb9baa02a63a2f83dec09c4153e1cfbdf9c2adef5c62c26d2160eeb067
F src/btree.c 8850125300b9780fa54bc45a41af88eb2796b90f2f97942279094beef9b0e971
F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
F src/build.c 611e07299d72ff04bbcb9e7109183467e30925d203c3e121ef9bb3cf6876289b
@@ -693,13 +688,13 @@ F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
F src/hash.c 03c8c0f4be9e8bcb6de65aa26d34a61d48a9430747084a69f9469fbb00ea52ca
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/hwtime.h d4d1b98c1afdc56986a5c0eba882786ef017e2180a320da25b4231b8e7e463e8
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd
F src/json.c fb031340edee159c07ad37dbe668ffe945ed86f525b0eb3822e4a67cbc498a72
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c a3bc9a2522dc3b960e38b7582d1818f6245a49289387c2c7b19f27bfeabf1e81
F src/main.c 65d11c17890966d271c925c6cc55e3ba50fa08374633cb99c0dee4719a20915a
F src/loadext.c 4747f72084dc80520a2d23e5bb0bc0760672208a81a2b115ce0b657acd65edf4
F src/main.c eaf5215917b7e8b34ddea013524287f6d5021ba0fc70202e7602e225ef0d16bf
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -723,23 +718,23 @@ F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae
F src/os_unix.c 7945ede1e85b2d1b910e1b4af9ba342e964b1e30e79f4176480a60736445cb36
F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f
F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
F src/pager.c cd562b878ea1b44d021ba199abc9d3b54f6b3347500a9fed03f66d6000620945
F src/pager.c a81461de271ac4886ad75b7ca2cca8157a48635820c4646cd2714acdc2c17e5f
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
F src/parse.y 619c3e92a54686c5e47923688c4b9bf7ec534a4690db5677acc28b299c403250
F src/parse.y 04c6c7278939e3c6307ed3c6ed7482d2928e692560dbe8e57f524851a934e25c
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd
F src/pragma.c ecec75795c1821520266e4f93fa8840cce48979af532db06f085e36a7813860f
F src/prepare.c 2af0b5c1ec787c8eebd21baa9d79caf4a4dc3a18e76ce2edbf2027d706bca37a
F src/printf.c 7297c2aeed4d90d80c5ba82920d9e57b7bfad04b3466be1d7e042db382fe296e
F src/printf.c b1b29b5e58e1530d5daeee5963d3c318d8ab2d7e38437580e28755753e0c1ded
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a
F src/shell.c.in 223e3703657f5e66c136521a32fc8cc9a7dbbe6b1ade6fd47457e78c38f33e6e
F src/sqlite.h.in c0979f9ac1f5be887397dd2a0bb485636893a81b34d64df85123aae9650c42f2
F src/shell.c.in ceb0a9cc008ac82d8d2e6ef353db14a54bc40dfd60a8cfbb6bc98d071f538761
F src/sqlite.h.in 667dff873941366da98da3200cf757ac05dfb62ea785e6642e33dd586ae5285c
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998
F src/sqliteInt.h 88f7fc9ce1630d9a5f7e0a8e1f3287cdc63882fba985c18e7eee1b9f457f59aa
F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
@@ -756,7 +751,7 @@ F src/test8.c 206d8f3cc73950d252906656e2646b5de0d580b07187b635fcb3edd8c2c5fbc0
F src/test9.c df9ddc7db6ef1b8cf745866ee229090779728bcbe660c7f297d3127ab21d92af
F src/test_autoext.c 14d4bbd3d0bd1eec0f6d16b29e28cf1e2d0b020d454835f0721a5f68121ac10f
F src/test_backup.c a2bfd90d2ff2511b8635507bdb30fa9b605ade19c16b533066cae3077f5bdb72
F src/test_bestindex.c a9428931bec06de830b2630f57a7b1f2711761269f04df62b7aa1affcbce15bb
F src/test_bestindex.c d75fad21369d80910238032bcf8d9ca1f2bffda13c1ceec63bfbb7f704448b15
F src/test_blob.c 77b994e17f2c87055f44fd96c9a206c5a7155bae2cda2769af60c2f3582f962c
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
F src/test_config.c 18aa596d37de1d5968c439fd58ebf38bc4d9c9d1db63621504e241fde375cecd
@@ -805,7 +800,7 @@ F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964
F src/vdbe.h be33bd7b17f2ec92939642416030491508c51071f6c14e27cd195983fec56b63
F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49
F src/vdbeapi.c 869a0da5d855495055f4d35c6ada582f64ce995ce14b26ff9d336274d497266c
F src/vdbeapi.c 6a2181cfd27c86b4cc1d8abb27ae11f3b3f0357567814fa276ec37b043542938
F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
F src/vdbemem.c 48e562ff27e6386eb8613207ac27d3d98c1f67fdc4775a1ab13759d2c2a1c021
@@ -1693,7 +1688,7 @@ F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl 463ae33b8bf75ac77451df19bd65e7c415c2e9891227c7c9e657d0a2d8e1074a
F test/testloadext.c 862b848783eaed9985fbce46c65cd214664376b549fae252b364d5d1ef350a27
F test/testrunner.tcl 60d7efa1816c5dfc37df3e3454b94b9042c0c8c50b27ae296d4a797cd309ace6 x
F test/testrunner.tcl 86179a8e78997e9257cb8f738c5624cb23897da5297855578ba74715e64f1602 x
F test/testrunner_data.tcl c507a9afa911c03446ed90442ffd4a98aca02882c3d51bd1177c24795674def8
F test/testrunner_estwork.tcl 7927a84327259a32854926f68a75292e33a61e7e052fdbfcb01f18696c99c724
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
@@ -2106,8 +2101,8 @@ F tool/genfkey.README e550911fa984c8255ebed2ef97824125d83806eb5232582700de949edf
F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a5a4f
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5
F tool/lemon.c 8f6c122e5727cb0e5f302b8efc91489b1947a8d98206d7a1b1cfc0ed685b6e7c
F tool/lempar.c bdffd3b233a4e4e78056c9c01fadd2bb3fe902435abde3bce3d769fdf0d5cca2
F tool/lemon.c fda0511d71764674919872a1457d2f86a7d48b13bfcf98741955c1b217a84570
F tool/lempar.c a59c5474bdd148ca4c61f2977c7ce6b49e99c48a333b6d48fc7ceacf2292b43a
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c 63412f9790e5e8538fbde0b4f6db154aaaf80f7a10a01e3c94d14b773a8dd5a6
F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669
@@ -2171,10 +2166,11 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 40ddaca3fb752425c26570365a9f31820786d21d043c1c0a4b49746ff9bc0782
R e6faec25512909b375a6de433bcc999d
T +sym-release *
T +sym-version-3.51.1 *
P ea48567ac54e4949a8b68977a58a5de7946e074ae8737133071d02f40ac97f34
R 94faba231c7b1fe01c357a8fbebddcb3
T *branch * parser-recursion-limit
T *sym-parser-recursion-limit *
T -sym-trunk *
U drh
Z a5cb39bb0c202daa26ad87d8a3e3f169
Z ef6a72fd333d3e7f2a3d9cd4902c91e6
# Remove this line to create a well-formed Fossil manifest.
+2 -4
View File
@@ -1,4 +1,2 @@
branch branch-3.51
tag release
tag branch-3.51
tag version-3.51.1
branch parser-recursion-limit
tag parser-recursion-limit
+1 -1
View File
@@ -1 +1 @@
281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88
5728129e5432500550096e2a1350897881f0379b49b60faf49481c505b1eb323
+25 -1
View File
@@ -3673,6 +3673,30 @@ static SQLITE_NOINLINE int btreeBeginTrans(
}
#endif
#ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114
/* If both a read and write transaction will be opened by this call,
** then issue a file-control as if the following pragma command had
** been evaluated:
**
** PRAGMA experimental_pragma_20251114 = 1|2
**
** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag
** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS.
**
** WARNING: This code will likely remain part of SQLite only temporarily -
** it exists to allow users to experiment with certain types of blocking
** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */
if( pBt->pPage1==0 && wrflag ){
sqlite3_file *fd = sqlite3PagerFile(pPager);
char *aFcntl[3] = {0,0,0};
aFcntl[1] = "experimental_pragma_20251114";
assert( wrflag==1 || wrflag==2 );
aFcntl[2] = (wrflag==1 ? "1" : "2");
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
sqlite3_free(aFcntl[0]);
}
#endif
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
@@ -9758,7 +9782,7 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){
}while( rc==SQLITE_OK && nOut>0 );
if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
Pgno pgnoNew;
Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */
MemPage *pNew = 0;
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
put4byte(pPgnoOut, pgnoNew);
+19 -21
View File
@@ -16,17 +16,18 @@
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
/*
** The following routine only works on Pentium-class (or newer) processors.
** It uses the RDTSC opcode to read the cycle count value out of the
** processor and returns that value. This can be used for high-res
** profiling.
*/
#if !defined(__STRICT_ANSI__) && \
(defined(__GNUC__) || defined(_MSC_VER)) && \
(defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(_MSC_VER) && defined(_WIN32)
#if defined(__GNUC__)
#include <profileapi.h>
__inline sqlite3_uint64 sqlite3Hwtime(void){
LARGE_INTEGER tm;
QueryPerformanceCounter(&tm);
return (sqlite3_uint64)tm.QuadPart;
}
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
(defined(i386) || defined(__i386__) || defined(_M_IX86))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned int lo, hi;
@@ -34,17 +35,6 @@
return (sqlite_uint64)hi << 32 | lo;
}
#elif defined(_MSC_VER)
__declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
__asm {
rdtsc
ret ; return value at EDX:EAX
}
}
#endif
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
@@ -52,6 +42,14 @@
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (sqlite_uint64)hi << 32 | lo;
}
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__)
__inline__ sqlite_uint64 sqlite3Hwtime(void){
sqlite3_uint64 cnt;
__asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt));
return cnt;
}
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
+4 -1
View File
@@ -522,7 +522,10 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_setlk_timeout,
/* Version 3.51.0 and later */
sqlite3_set_errmsg,
sqlite3_db_status64
sqlite3_db_status64,
/* Version 3.52.0 and later */
sqlite3_str_truncate,
sqlite3_str_free
};
/* True if x is the directory separator character
+9
View File
@@ -2526,6 +2526,9 @@ void *sqlite3_wal_hook(
sqlite3_mutex_leave(db->mutex);
return pRet;
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(xCallback);
UNUSED_PARAMETER(pArg);
return 0;
#endif
}
@@ -2541,6 +2544,11 @@ int sqlite3_wal_checkpoint_v2(
int *pnCkpt /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(zDb);
UNUSED_PARAMETER(eMode);
UNUSED_PARAMETER(pnLog);
UNUSED_PARAMETER(pnCkpt);
return SQLITE_OK;
#else
int rc; /* Return code */
@@ -4903,6 +4911,7 @@ const char *sqlite3_filename_journal(const char *zFilename){
}
const char *sqlite3_filename_wal(const char *zFilename){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(zFilename);
return 0;
#else
zFilename = sqlite3_filename_journal(zFilename);
+4
View File
@@ -813,6 +813,8 @@ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
if( iRead ) return 0; /* Case (4) */
}
#else
UNUSED_PARAMETER(pgno);
#endif
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
@@ -4192,6 +4194,8 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
pPager->pWal = 0;
}
#else
UNUSED_PARAMETER(db);
#endif
pager_reset(pPager);
if( MEMDB ){
+14 -5
View File
@@ -22,8 +22,8 @@
}
// Function used to enlarge the parser stack, if needed
%realloc parserStackRealloc
%free sqlite3_free
%reallocx parserStackRealloc
%free sqlite3_free
// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_
@@ -49,7 +49,7 @@
}
}
%stack_overflow {
sqlite3OomFault(pParse->db);
if( pParse->nErr==0 ) sqlite3OomFault(pParse->db);
}
// The name of the generated procedure that implements the parser
@@ -583,8 +583,17 @@ cmd ::= select(X). {
** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
** testing.
*/
static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
static void *parserStackRealloc(
void *pOld, /* Old allocation, or NULL to get a new one */
int newCount, /* Number of elements */
int unitSize, /* Size of each element */
Parse *pParse /* Parsing context */
){
if( sqlite3FaultSim(700) ) return 0;
if( newCount > pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]*4+100 ){
sqlite3ErrorMsg(pParse, "Recursion limit reached");
}
return sqlite3_realloc64(pOld, newCount*unitSize);
}
}
+19
View File
@@ -1228,6 +1228,14 @@ int sqlite3_str_length(sqlite3_str *p){
return p ? p->nChar : 0;
}
/* Truncate the text of the string to be no more than N bytes. */
void sqlite3_str_truncate(sqlite3_str *p, int N){
if( p!=0 && N>=0 && (u32)N<p->nChar ){
p->nChar = N;
p->zText[p->nChar] = 0;
}
}
/* Return the current value for p */
char *sqlite3_str_value(sqlite3_str *p){
if( p==0 || p->nChar==0 ) return 0;
@@ -1248,6 +1256,17 @@ void sqlite3_str_reset(StrAccum *p){
p->zText = 0;
}
/*
** Destroy a dynamically allocate sqlite3_str object and all
** of its content, all in one call.
*/
void sqlite3_str_free(sqlite3_str *p){
if( p ){
sqlite3_str_reset(p);
sqlite3_free(p);
}
}
/*
** Initialize a string accumulator.
**
+26 -23
View File
@@ -7225,39 +7225,42 @@ static void clearTempFile(ShellState *p){
p->zTempFile = 0;
}
/* Forward reference */
static char *find_home_dir(int clearFlag);
/*
** Create a new temp file name with the given suffix.
**
** Because the classic temp folders like /tmp are no longer
** accessible to web browsers, for security reasons, create the
** temp file in the user's home directory.
*/
static void newTempFile(ShellState *p, const char *zSuffix){
char *zHome; /* Home directory */
int i; /* Loop counter */
sqlite3_uint64 r = 0; /* Integer with 64 bits of randomness */
char zRand[32]; /* Text string with 160 bits of randomness */
#ifdef _WIN32
const char cDirSep = '\\';
#else
const char cDirSep = '/';
#endif
for(i=0; i<31; i++){
if( (i%12)==0 ) sqlite3_randomness(sizeof(r),&r);
zRand[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[r%36];
r /= 36;
}
zRand[i] = 0;
clearTempFile(p);
sqlite3_free(p->zTempFile);
p->zTempFile = 0;
if( p->db ){
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
}
if( p->zTempFile==0 ){
/* If p->db is an in-memory database then the TEMPFILENAME file-control
** will not work and we will need to fallback to guessing */
char *zTemp;
sqlite3_uint64 r;
sqlite3_randomness(sizeof(r), &r);
zTemp = getenv("TEMP");
if( zTemp==0 ) zTemp = getenv("TMP");
if( zTemp==0 ){
#ifdef _WIN32
zTemp = "\\tmp";
#else
zTemp = "/tmp";
#endif
}
p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
}else{
p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
}
zHome = find_home_dir(0);
p->zTempFile = sqlite3_mprintf("%s%ctemp-%s.%s",
zHome,cDirSep,zRand,zSuffix);
shell_check_oom(p->zTempFile);
}
/*
** The implementation of SQL scalar function fkey_collate_clause(), used
** by the ".lint fkey-indexes" command. This scalar function is always
+26 -12
View File
@@ -2567,12 +2567,15 @@ struct sqlite3_mem_methods {
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
** statistics. For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is prepared and when it
** is stepped. The flag is set (collection of statistics is enabled)
** by default. <p>This option takes two arguments: an integer and a pointer to
** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
** a flag that enables collection of run-time performance statistics
** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
** columns of the [bytecode virtual table].
** For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is
** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
** The flag is set (collection of statistics is enabled) by default.
** <p>This option takes two arguments: an integer and a pointer to
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
** leave unchanged the statement scanstatus option. If the second argument
** is not NULL, then the value of the statement scanstatus setting after
@@ -4217,7 +4220,7 @@ const char *sqlite3_errstr(int);
int sqlite3_error_offset(sqlite3 *db);
/*
** CAPI3REF: Set Error Codes And Message
** CAPI3REF: Set Error Code And Message
** METHOD: sqlite3
**
** Set the error code of the database handle passed as the first argument
@@ -8724,15 +8727,20 @@ sqlite3_str *sqlite3_str_new(sqlite3*);
** errors were encountered during construction of the string. ^The
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
** string in [sqlite3_str] object X is zero bytes long.
**
** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
** X and the string content it contains. Calling sqlite3_str_free(X) is
** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
*/
char *sqlite3_str_finish(sqlite3_str*);
void sqlite3_str_free(sqlite3_str*);
/*
** CAPI3REF: Add Content To A Dynamic String
** METHOD: sqlite3_str
**
** These interfaces add content to an sqlite3_str object previously obtained
** from [sqlite3_str_new()].
** These interfaces add or remove content to an sqlite3_str object
** previously obtained from [sqlite3_str_new()].
**
** ^The [sqlite3_str_appendf(X,F,...)] and
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
@@ -8755,6 +8763,10 @@ char *sqlite3_str_finish(sqlite3_str*);
** ^The [sqlite3_str_reset(X)] method resets the string under construction
** inside [sqlite3_str] object X back to zero bytes in length.
**
** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
** under construction to be N bytes are less. This routine is a no-op if
** N is negative or if the string is already N bytes or smaller in size.
**
** These methods do not return a result code. ^If an error occurs, that fact
** is recorded in the [sqlite3_str] object and can be recovered by a
** subsequent call to [sqlite3_str_errcode(X)].
@@ -8765,6 +8777,7 @@ void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
void sqlite3_str_reset(sqlite3_str*);
void sqlite3_str_truncate(sqlite3_str*,int N);
/*
** CAPI3REF: Status Of A Dynamic String
@@ -10598,9 +10611,9 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
** a variable pointed to by the "pOut" parameter.
**
** The "flags" parameter must be passed a mask of flags. At present only
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
** is specified, then status information is available for all elements
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
** the EXPLAIN QUERY PLAN output) are available. Invoking API
@@ -10614,7 +10627,8 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
** elements used to implement the statement - a non-zero value is returned and
** the variable that pOut points to is unchanged.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
** See also: [sqlite3_stmt_scanstatus_reset()] and the
** [nexec and ncycle] columnes of the [bytecode virtual table].
*/
int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
+6 -1
View File
@@ -371,7 +371,9 @@ struct sqlite3_api_routines {
/* Version 3.51.0 and later */
int (*set_errmsg)(sqlite3*,int,const char*);
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
/* Version 3.52.0 and later */
void (*str_truncate)(sqlite3_str*,int);
void (*str_free)(sqlite3_str*);
};
/*
@@ -710,6 +712,9 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.51.0 and later */
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
#define sqlite3_db_status64 sqlite3_api->db_status64
/* Version 3.52.0 and later */
#define sqlite3_str_truncate sqlite3_api->str_truncate
#define sqlite3_str_free sqlite3_api->str_free
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
-1
View File
@@ -828,7 +828,6 @@ static int tclUpdate(
tcl_vtab *pTab = (tcl_vtab*)tab;
Tcl_Interp *interp = pTab->interp;
Tcl_Obj *pEval = Tcl_DuplicateObj(pTab->pCmd);
Tcl_Obj *pRes = 0;
int rc = TCL_OK;
Tcl_IncrRefCount(pEval);
+2
View File
@@ -736,6 +736,8 @@ static int doWalCallbacks(sqlite3 *db){
}
}
}
#else
UNUSED_PARAMETER(db);
#endif
return rc;
}
+20
View File
@@ -1269,6 +1269,26 @@ proc add_fuzztest_jobs {buildname patternlist} {
set subcmd [lrange $interpreter 1 end]
set interpreter [lindex $interpreter 0]
# For fuzzcheck-asan and fuzzcheck-ubsan, break up some
# fuzzdata files into multiple slices, for improved
# concurrency.
#
if {[string match *fuzzcheck-*san $interpreter]} {
set newscripts {}
foreach s $scripts {
if {[string match {*fuzzdata[12].db} $s]
&& ![string match slice $s]} {
set N 6
for {set i 0} {$i<$N} {incr i} {
lappend newscripts [list --slice $i $N $s]
}
} else {
lappend newscripts $s
}
}
set scripts $newscripts
}
if {[string match fuzzcheck* $interpreter]
&& [info exists env(FUZZDB)]
&& [file readable $env(FUZZDB)]
+23 -16
View File
@@ -495,6 +495,7 @@ struct lemon {
char *outname; /* Name of the current output file */
char *tokenprefix; /* A prefix added to token names in the .h file */
char *reallocFunc; /* Function to use to allocate stack space */
char *reallocFuncEx; /* Alternative realloc() with context pointer */
char *freeFunc; /* Function to use to free stack space */
int nconflict; /* Number of parsing conflicts */
int nactiontab; /* Number of entries in the yy_action[] table */
@@ -2641,6 +2642,9 @@ static void parseonetoken(struct pstate *psp)
}else if( strcmp(x,"realloc")==0 ){
psp->declargslot = &(psp->gp->reallocFunc);
psp->insertLineMacro = 0;
}else if( strcmp(x,"reallocx")==0 ){
psp->declargslot = &(psp->gp->reallocFuncEx);
psp->insertLineMacro = 0;
}else if( strcmp(x,"free")==0 ){
psp->declargslot = &(psp->gp->freeFunc);
psp->insertLineMacro = 0;
@@ -4414,7 +4418,7 @@ void ReportTable(
int mhflag, /* Output in makeheaders format if true */
int sqlFlag /* Generate the *.sql file too */
){
FILE *out, *in, *sql;
FILE *out, *in;
int lineno;
struct state *stp;
struct action *ap;
@@ -4439,18 +4443,10 @@ void ReportTable(
in = tplt_open(lemp);
if( in==0 ) return;
out = file_open(lemp,".c","wb");
if( out==0 ){
fclose(in);
return;
}
if( sqlFlag==0 ){
sql = 0;
}else{
sql = file_open(lemp, ".sql", "wb");
if( sqlFlag ){
FILE *sql = file_open(lemp, ".sql", "wb");
if( sql==0 ){
fclose(in);
fclose(out);
return;
}
fprintf(sql,
@@ -4515,6 +4511,12 @@ void ReportTable(
}
}
fprintf(sql, "COMMIT;\n");
fclose(sql);
}
out = file_open(lemp,".c","wb");
if( out==0 ){
fclose(in);
return;
}
lineno = 1;
@@ -4612,17 +4614,21 @@ void ReportTable(
fprintf(out,"#define %sARG_FETCH\n",name); lineno++;
fprintf(out,"#define %sARG_STORE\n",name); lineno++;
}
if( lemp->reallocFunc ){
fprintf(out,"#define YYREALLOC %s\n", lemp->reallocFunc); lineno++;
if( lemp->reallocFuncEx ){
fprintf(out,"#define YYREALLOC(A,B,C,D) %s(A,B,C,D)\n",
lemp->reallocFuncEx); lineno++;
}else if( lemp->reallocFunc ){
fprintf(out,"#define YYREALLOC(A,B,C,D) %s(A,B*C)\n",
lemp->reallocFunc); lineno++;
}else{
fprintf(out,"#define YYREALLOC realloc\n"); lineno++;
fprintf(out,"#define YYREALLOC(A,B,C,D) realloc(A,B*C)\n"); lineno++;
}
if( lemp->freeFunc ){
fprintf(out,"#define YYFREE %s\n", lemp->freeFunc); lineno++;
}else{
fprintf(out,"#define YYFREE free\n"); lineno++;
}
if( lemp->reallocFunc && lemp->freeFunc ){
if( (lemp->reallocFunc || lemp->reallocFuncEx) && lemp->freeFunc ){
fprintf(out,"#define YYDYNSTACK 1\n"); lineno++;
}else{
fprintf(out,"#define YYDYNSTACK 0\n"); lineno++;
@@ -4634,6 +4640,7 @@ void ReportTable(
fprintf(out,"#define %sCTX_SDECL %s;\n",name,lemp->ctx); lineno++;
fprintf(out,"#define %sCTX_PDECL ,%s\n",name,lemp->ctx); lineno++;
fprintf(out,"#define %sCTX_PARAM ,%s\n",name,&lemp->ctx[i]); lineno++;
fprintf(out,"#define %sCTX_FIELD %s\n",name,&lemp->ctx[i]); lineno++;
fprintf(out,"#define %sCTX_FETCH %s=yypParser->%s;\n",
name,lemp->ctx,&lemp->ctx[i]); lineno++;
fprintf(out,"#define %sCTX_STORE yypParser->%s=%s;\n",
@@ -4642,6 +4649,7 @@ void ReportTable(
fprintf(out,"#define %sCTX_SDECL\n",name); lineno++;
fprintf(out,"#define %sCTX_PDECL\n",name); lineno++;
fprintf(out,"#define %sCTX_PARAM\n",name); lineno++;
fprintf(out,"#define %sCTX_FIELD yyhwm\n", name); lineno++;
fprintf(out,"#define %sCTX_FETCH\n",name); lineno++;
fprintf(out,"#define %sCTX_STORE\n",name); lineno++;
}
@@ -5103,7 +5111,6 @@ void ReportTable(
acttab_free(pActtab);
fclose(in);
fclose(out);
if( sql ) fclose(sql);
return;
}
+2 -2
View File
@@ -303,11 +303,11 @@ static int yyGrowStack(yyParser *p){
newSize = oldSize*2 + 100;
idx = (int)(p->yytos - p->yystack);
if( p->yystack==p->yystk0 ){
pNew = YYREALLOC(0, newSize*sizeof(pNew[0]));
pNew = YYREALLOC(0,newSize,sizeof(pNew[0]), p->ParseCTX_FIELD);
if( pNew==0 ) return 1;
memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
}else{
pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]));
pNew = YYREALLOC(p->yystack,newSize,sizeof(pNew[0]),p->ParseCTX_FIELD);
if( pNew==0 ) return 1;
}
p->yystack = pNew;