From cc1cc9d7b78a6c932d7f6201106c7b4ef094ea30 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 11:46:26 +0000 Subject: [PATCH 1/8] Initial pieces for binding the session API to JS. Far from complete. See [forum:210e36a1e3 | forum post 210e36a1e3] for the discussion. FossilOrigin-Name: cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 --- ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api | 47 +++++++++++++++++++-- ext/wasm/api/sqlite3-api-glue.js | 12 ++++-- ext/wasm/api/sqlite3-wasm.c | 6 +++ manifest | 19 +++++---- manifest.uuid | 2 +- 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index 75e5ea3da1..2c94d0fada 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -1,3 +1,6 @@ +_malloc +_free +_realloc _sqlite3_aggregate_context _sqlite3_bind_blob _sqlite3_bind_double @@ -143,6 +146,44 @@ _sqlite3_vtab_in_next _sqlite3_vtab_nochange _sqlite3_vtab_on_conflict _sqlite3_vtab_rhs_value -_malloc -_free -_realloc +_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_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_patchset +_sqlite3session_patchset_strm +_sqlite3session_table_filter diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 59b40786ec..958f1b845b 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -332,10 +332,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(1){// WhWasmUtil.xWrap() bindings... /** Add some descriptive xWrap() aliases for '*' intended to (A) - initially improve readability/correctness of capi.signatures - and (B) provide automatic conversion from higher-level - representations, e.g. capi.sqlite3_vfs to `sqlite3_vfs*` via - capi.sqlite3_vfs.pointer. + initially improve readability/correctness of + wasm.bindingSignatures and (B) provide automatic conversion + from higher-level representations, e.g. capi.sqlite3_vfs to + `sqlite3_vfs*` via capi.sqlite3_vfs.pointer. */ const aPtr = wasm.xWrap.argAdapter('*'); const nilType = function(){}; @@ -343,6 +343,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ('sqlite3_context*', aPtr) ('sqlite3_value*', aPtr) ('void*', aPtr) + ('sqlite3_changegroup*', aPtr) + ('sqlite3_changeset_iter*', aPtr) + //('sqlite3_rebaser*', aPtr) + ('sqlite3_session*', aPtr) ('sqlite3_stmt*', (v)=> aPtr((v instanceof (sqlite3?.oo1?.Stmt || nilType)) ? v.pointer : v)) diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index a42ea68d42..34e7a63ee8 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -102,9 +102,15 @@ #ifndef SQLITE_ENABLE_OFFSET_SQL_FUNC # define SQLITE_ENABLE_OFFSET_SQL_FUNC 1 #endif +#ifndef SQLITE_ENABLE_PREUPDATE_HOOK +# define SQLITE_ENABLE_PREUPDATE_HOOK 1 /*required by session extension*/ +#endif #ifndef SQLITE_ENABLE_RTREE # define SQLITE_ENABLE_RTREE 1 #endif +#ifndef SQLITE_ENABLE_SESSION +# define SQLITE_ENABLE_SESSION 1 +#endif #ifndef SQLITE_ENABLE_STMTVTAB # define SQLITE_ENABLE_STMTVTAB 1 #endif diff --git a/manifest b/manifest index 1a675a0239..6d1e106dfb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Squelch\sa\snew\s(and,\sin\sthis\scase,\sharmless)\scompiler\swarning. -D 2022-12-23T11:32:06.928 +C Initial\spieces\sfor\sbinding\sthe\ssession\sAPI\sto\sJS.\sFar\sfrom\scomplete.\sSee\s[forum:210e36a1e3\s|\sforum\spost\s210e36a1e3]\sfor\sthe\sdiscussion. +D 2022-12-23T11:46:26.185 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile 06d385b51bfb206cf779cf1bb816862f77df97fff97a6df9baf05b98c027067a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 4c7788042196cecab32f87d8e4965c183fea59037603888059f244b1752babcc +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api ff6f8c477f6f38457bce1c604ac517ecc3dfea64f816dc90356c0402f96725b8 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 63daa4b9c36faa4c338a32a06eb142869b9ae4885a3e01aad473e1b45357089f +F ext/wasm/api/sqlite3-api-glue.js dfdfbcdf1a9d4e42836ec53fda02c70869cfe5651a75e785b62ff69c4fe822e2 F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6 F ext/wasm/api/sqlite3-api-prologue.js 1767dfcd94bb4fa9dd4bd9ff6327117783d3656faf1058dcc1369db320d871fc F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -512,7 +512,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 44ce4cf12318b0577d8222cf59132617ab9925ca3cf5fbb8c7b30d1e947c13b5 +F ext/wasm/api/sqlite3-wasm.c 15194e3d5e0bcbcdcafb928392438d83aed56bdb8e71984ac415cc6a3b75e602 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -2067,8 +2067,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7b5900a111b9410f7d60c937e5a56304f2f66b94cd0881e94abcc5eedde52514 -R e60c0e3c20a0e7bf83aa49203eb3c182 +P a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd +R 754103df3bb98463a7b36626ed444e4f +T *branch * wasm-session-api +T *sym-wasm-session-api * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z 6976083f5240fdbe68fe33f0caf6e410 +Z bbc6e7158315d4288a4f21a6ce2dd790 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 20c91dded8..49a23b524f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd \ No newline at end of file +cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 \ No newline at end of file From 0f29f17bf6ea1044d4daa7bbc00283a026a1c514 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 14:11:54 +0000 Subject: [PATCH 2/8] Add sqlite3.capi JS bindings for the sqlite3session_...(), sqlite3changeset_...() and sqlite3changegroup_...() APIs, noting that they are completely untested. Aside from missing tests, these bindings reveal a slight string-argument-type shortcoming in the callback function pointer "reverse binding" which should ideally be resolved before publishing them. FossilOrigin-Name: 0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d --- ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api | 1 + ext/wasm/api/sqlite3-api-glue.js | 213 +++++++++++++++++++- ext/wasm/api/sqlite3-wasm.c | 21 ++ ext/wasm/common/whwasmutil.js | 20 +- manifest | 21 +- manifest.uuid | 2 +- 6 files changed, 249 insertions(+), 29 deletions(-) diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index 2c94d0fada..da4cc5bd21 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -184,6 +184,7 @@ _sqlite3session_enable _sqlite3session_indirect _sqlite3session_isempty _sqlite3session_memory_used +_sqlite3session_object_config _sqlite3session_patchset _sqlite3session_patchset_strm _sqlite3session_table_filter diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 958f1b845b..dc1e827d50 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -59,10 +59,16 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ the lines of sqlite3_prepare_v3(). The slightly problematic part is the final argument (text destructor). */ ], - //["sqlite3_busy_handler","int", "sqlite3*", "*", "*"], - // ^^^^ TODO: custom binding which auto-converts JS function arg - // to a WASM function, noting that calling it multiple times - // would introduce a leak. + ["sqlite3_busy_handler","int", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: 'sqlite3_busy_handler', + signature: 'i(pi)', + bindScope: 'context', + contextKey: (argIndex,argv)=>'sqlite3@'+argv[0] + }), + "*" + ]], ["sqlite3_busy_timeout","int", "sqlite3*", "int"], ["sqlite3_close_v2", "int", "sqlite3*"], ["sqlite3_changes", "int", "sqlite3*"], @@ -131,14 +137,16 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ for those, depending on how their SQL argument is provided. */ /* sqlite3_randomness() uses a hand-written wrapper to extend the range of supported argument types. */ - [ + [ "sqlite3_progress_handler", undefined, [ - "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({ + "sqlite3*", "int", + new wasm.xWrap.FuncPtrAdapter({ name: 'xProgressHandler', signature: 'i(p)', bindScope: 'context', contextKey: (argIndex,argv)=>'sqlite3@'+argv[0] - }), "*" + }), + "*" ] ], ["sqlite3_realloc", "*","*","int"], @@ -211,7 +219,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ optional features into account. */ wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]); } - + /** Functions which require BigInt (int64) support are separated from the others because we need to conditionally bind them or apply @@ -263,6 +271,187 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"] ]; + // Add session/changeset APIs... + if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){ + /* ACHTUNG: 2022-12-23: the session/changeset API bindings are + COMPLETELY UNTESTED. Additionally, the callback-taking APIs + have a shortcoming which will make using those which take + string-type arguments more painful than it should be. How best + to resolve that, such that we can perform the same type conversions + as we do when binding in "the other direction," is as yet + undetermined. + */ + /* TODO: we need hand-written wrappers to adapt callbacks which + take string arguments. Or we need to find a way to do this sort + of reverse-binding which includes type conversions. */ + wasm.bindingSignatures.int64.push(...[ + ['sqlite3changegroup_add', 'int', ['sqlite3_changegroup*', 'int', 'void*']], + ['sqlite3changegroup_add_strm', 'int', [ + 'sqlite3_changegroup*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changegroup_delete', undefined, ['sqlite3_changegroup*']], + ['sqlite3changegroup_new', 'int', ['**']], + ['sqlite3changegroup_output', 'int', ['sqlite3_changegroup*', 'int*', '**']], + ['sqlite3changegroup_output_strm', 'int', [ + 'sqlite3_changegroup*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppi)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_apply', 'int', [ + 'sqlite3*', 'int', 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_apply_strm', 'int', [ + 'sqlite3*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_apply_v2', 'int', [ + 'sqlite3*', 'int', 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*', '**', 'int*', 'int' + + ]], + ['sqlite3changeset_apply_v2', 'int', [ + 'sqlite3*', 'int', 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*', '**', 'int*', 'int' + ]], + ['sqlite3changeset_apply_v2_strm', 'int', [ + 'sqlite3*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*', '**', 'int*', 'int' + ]], + ['sqlite3changeset_concat', 'int', ['int','void*', 'int', 'void*', 'int*', '**']], + ['sqlite3changeset_concat_strm', 'int', [ + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInputA', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInputB', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppi)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_conflict', 'int', ['sqlite3_changeset_iter*', 'int', '**']], + ['sqlite3changeset_finalize', 'int', ['sqlite3_changeset_iter*']], + ['sqlite3changeset_fk_conflicts', 'int', ['sqlite3_changeset_iter*', 'int*']], + ['sqlite3changeset_invert', 'int', ['int', 'void*', 'int*', '**']], + ['sqlite3changeset_invert_strm', 'int', [ + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppi)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_new', 'int', ['sqlite3_changeset_iter*', 'int', '**']], + ['sqlite3changeset_next', 'int', ['sqlite3_changeset_iter*']], + ['sqlite3changeset_old', 'int', ['sqlite3_changeset_iter*', 'int', '**']], + ['sqlite3changeset_op', 'int', [ + 'sqlite3_changeset_iter*', '**', 'int*', 'int*','int*' + ]], + ['sqlite3changeset_pk', 'int', ['sqlite3_changeset_iter*', '**', 'int*']], + ['sqlite3changeset_start', 'int', ['**', 'int', '*']], + ['sqlite3changeset_start_strm', 'int', [ + '**', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_start_v2', 'int', ['**', 'int', '*', 'int']], + ['sqlite3changeset_start_v2_strm', 'int', [ + '**', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', 'int' + ]], + ['sqlite3session_attach', 'int', ['sqlite3_session*', 'string']], + ['sqlite3session_changeset', 'int', ['sqlite3_session*', 'int*', '**']], + ['sqlite3session_changeset_size', 'i64', ['sqlite3_session*']], + ['sqlite3session_changeset_strm', 'int', [ + 'sqlite3_session*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3session_config', 'int', ['int', 'void*']], + ['sqlite3session_create', 'int', ['sqlite3*', 'string', '**']], + ['sqlite3session_delete', undefined, ['sqlite3_session*']], + ['sqlite3session_diff', 'int', ['sqlite3_session*', 'string', 'string', '**']], + ['sqlite3session_enable', 'int', ['sqlite3_session*', 'int']], + ['sqlite3session_indirect', 'int', ['sqlite3_session*', 'int']], + ['sqlite3session_isempty', 'int', ['sqlite3_session*']], + ['sqlite3session_memory_used', 'i64', ['sqlite3_session*']], + ['sqlite3session_object_config', 'int', ['sqlite3_session*', 'int', 'void*']], + ['sqlite3session_patchset', 'int', ['sqlite3_session*', '*', '**']], + ['sqlite3session_patchset_strm', 'int', [ + 'sqlite3_session*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3session_table_filter', undefined, [ + 'sqlite3_session*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', + contextKey: (argIndex,argv)=>argv[0/* (sqlite3_session*) */] + }), + '*' + ]] + ]); + }/*session/changeset APIs*/ + /** Functions which are intended solely for API-internal use by the WASM components, not client code. These get installed into @@ -513,7 +702,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ); } let rc, pfCompare, pfDestroy; - try{ + try{ rc = __ccv2(pDb, zName, eTextRep, pArg, xCompare, xDestroy); }catch(e){ rc = util.sqlite3_wasm_db_error(pDb, e); @@ -910,12 +1099,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.ctype = JSON.parse(wasm.cstrToJs(cJson)); //console.debug('wasm.ctype length =',wasm.cstrlen(cJson)); const defineGroups = ['access', 'authorizer', - 'blobFinalizers', 'config', 'dataTypes', + 'blobFinalizers', 'changeset', + 'config', 'dataTypes', 'dbConfig', 'dbStatus', 'encodings', 'fcntl', 'flock', 'ioCap', 'limits', 'openFlags', 'prepareFlags', 'resultCodes', - 'serialize', 'sqlite3Status', + 'serialize', 'session', + 'sqlite3Status', 'stmtStatus', 'syncFlags', 'trace', 'txnState', 'udfFlags', 'version' ]; diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index 34e7a63ee8..39720ff9d1 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -461,6 +461,22 @@ const char * sqlite3_wasm_enum_json(void){ out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1"); } _DefGroup; + DefGroup(changeset){ + DefInt(SQLITE_CHANGESETSTART_INVERT); + DefInt(SQLITE_CHANGESETAPPLY_NOSAVEPOINT); + DefInt(SQLITE_CHANGESETAPPLY_INVERT); + + DefInt(SQLITE_CHANGESET_DATA); + DefInt(SQLITE_CHANGESET_NOTFOUND); + DefInt(SQLITE_CHANGESET_CONFLICT); + DefInt(SQLITE_CHANGESET_CONSTRAINT); + DefInt(SQLITE_CHANGESET_FOREIGN_KEY); + + DefInt(SQLITE_CHANGESET_OMIT); + DefInt(SQLITE_CHANGESET_REPLACE); + DefInt(SQLITE_CHANGESET_ABORT); + } _DefGroup; + DefGroup(config){ DefInt(SQLITE_CONFIG_SINGLETHREAD); DefInt(SQLITE_CONFIG_MULTITHREAD); @@ -797,6 +813,11 @@ const char * sqlite3_wasm_enum_json(void){ DefInt(SQLITE_DESERIALIZE_RESIZEABLE); } _DefGroup; + DefGroup(session){ + DefInt(SQLITE_SESSION_CONFIG_STRMSIZE); + DefInt(SQLITE_SESSION_OBJCONFIG_SIZE); + } _DefGroup; + DefGroup(sqlite3Status){ DefInt(SQLITE_STATUS_MEMORY_USED); DefInt(SQLITE_STATUS_PAGECACHE_USED); diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 87cc100f33..c99e36041b 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -446,7 +446,7 @@ self.WhWasmUtilInstaller = function(target){ type(s) of the given function signature, or throws if the signature is invalid. */ /******** // only valid for use with the WebAssembly.Function ctor, which - // is not yet documented on MDN. + // is not yet documented on MDN. sigToWasm: function(sig){ const rc = {parameters:[], results: []}; if('v'!==sig[0]) rc.results.push(f.sigTypes(sig[0])); @@ -1581,10 +1581,20 @@ self.WhWasmUtilInstaller = function(target){ not actually bind any functions. Its convertArg() method is called via xWrap() to perform any bindings. - Shortcomings: function pointers which include C-string arguments - may still need a level of hand-written wrappers around them, - depending on how they're used, in order to provide the client - with JS strings. + Shortcomings: + + - These "reverse" bindings, i.e. calling into a JS-defined + function from a WASM-defined function (the generated proxy + wrapper), lack all type conversion support. That means, for + example, that... + + - Function pointers which include C-string arguments may still + need a level of hand-written wrappers around them, depending on + how they're used, in order to provide the client with JS + strings. Alternately, clients will need to perform such conversions + on their own, e.g. using cstrtojs(). Or maybe we can find a way + to perform such conversions here, via addition of an xWrap()-style + function signature to the options argument. */ xArg.FuncPtrAdapter = class FuncPtrAdapter extends AbstractArgAdapter { constructor(opt) { diff --git a/manifest b/manifest index 6d1e106dfb..eacaf992fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\spieces\sfor\sbinding\sthe\ssession\sAPI\sto\sJS.\sFar\sfrom\scomplete.\sSee\s[forum:210e36a1e3\s|\sforum\spost\s210e36a1e3]\sfor\sthe\sdiscussion. -D 2022-12-23T11:46:26.185 +C Add\ssqlite3.capi\sJS\sbindings\sfor\sthe\ssqlite3session_...(),\ssqlite3changeset_...()\sand\ssqlite3changegroup_...()\sAPIs,\snoting\sthat\sthey\sare\scompletely\suntested.\sAside\sfrom\smissing\stests,\sthese\sbindings\sreveal\sa\sslight\sstring-argument-type\sshortcoming\sin\sthe\scallback\sfunction\spointer\s"reverse\sbinding"\swhich\sshould\sideally\sbe\sresolved\sbefore\spublishing\sthem. +D 2022-12-23T14:11:54.508 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile 06d385b51bfb206cf779cf1bb816862f77df97fff97a6df9baf05b98c027067a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api ff6f8c477f6f38457bce1c604ac517ecc3dfea64f816dc90356c0402f96725b8 +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 8c15a035ca5263659f21a691d701e23294621a24d1e130fa8905a261b495ebe4 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js dfdfbcdf1a9d4e42836ec53fda02c70869cfe5651a75e785b62ff69c4fe822e2 +F ext/wasm/api/sqlite3-api-glue.js 5a28c384ece2066522cf8b04a454d44c0245835a6a26b681d3deed97b3805623 F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6 F ext/wasm/api/sqlite3-api-prologue.js 1767dfcd94bb4fa9dd4bd9ff6327117783d3656faf1058dcc1369db320d871fc F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -512,7 +512,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 15194e3d5e0bcbcdcafb928392438d83aed56bdb8e71984ac415cc6a3b75e602 +F ext/wasm/api/sqlite3-wasm.c f0aafd3e8f09c68bec14bd0cc7a31212964302134dec8c428e7afc517e78e257 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js ba1a8db1f32124e43e24b3d890102b6552b2c0b5a202185041a55887692df328 +F ext/wasm/common/whwasmutil.js af85d9a09fa79847d08279be0f61978ecc3bed893c88003f4a85d8bd204e6b5a F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,11 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd -R 754103df3bb98463a7b36626ed444e4f -T *branch * wasm-session-api -T *sym-wasm-session-api * -T -sym-trunk * Cancelled\sby\sbranch. +P cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 +R 042a575edf17a004d3f3655705629da7 U stephan -Z bbc6e7158315d4288a4f21a6ce2dd790 +Z 81bf3460fe50c1e6a01aac07ed8bed30 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 49a23b524f..aa150a668b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 \ No newline at end of file +0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d \ No newline at end of file From b5915699d0404bcd3b502e18af3d889d0bf581dc Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 18:14:36 +0000 Subject: [PATCH 3/8] Internal cleanups and minor speed optimizations in the sqlite3.wasm.xWrap() infrastructure. FossilOrigin-Name: c4dab53b8ea3401abd57671b8f3cb39fa4431b864d4c4e14ae24592f8d4cba0a --- ext/wasm/common/whwasmutil.js | 205 +++++++++++++++++++--------------- ext/wasm/tester1.c-pp.js | 64 ++++++++++- manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 182 insertions(+), 103 deletions(-) diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index c99e36041b..4b1026e4cd 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -359,7 +359,8 @@ self.WhWasmUtilInstaller = function(target){ /** Given a function pointer, returns the WASM function table entry - if found, else returns a falsy value. + if found, else returns a falsy value: undefined if fptr is out of + range or null if it's in range but the table entry is empty. */ target.functionEntry = function(fptr){ const ft = target.functionTable(); @@ -552,13 +553,12 @@ self.WhWasmUtilInstaller = function(target){ cache.scopedAlloc[cache.scopedAlloc.length-1].push(ptr); } }catch(e){ - if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen); - throw e; + if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen); + throw e; } - return ptr; + return ptr; }; - /** Expects a JS function and signature, exactly as for this.jsFuncToWasm(). It uses that function to create a @@ -612,8 +612,13 @@ self.WhWasmUtilInstaller = function(target){ installFunction() has been called and results are undefined if ptr was not returned by that function. The returned function may be passed back to installFunction() to reinstall it. + + To simplify certain use cases, if passed a falsy non-0 value + (noting that 0 is a valid function table index), this function + has no side effects and returns undefined. */ target.uninstallFunction = function(ptr){ + if(!ptr && 0!==ptr) return undefined; const fi = cache.freeFuncIndexes; const ft = target.functionTable(); fi.push(ptr); @@ -730,7 +735,7 @@ self.WhWasmUtilInstaller = function(target){ ? cache : heapWrappers(); for(const p of (Array.isArray(ptr) ? ptr : [ptr])){ switch (type) { - case 'i1': + case 'i1': case 'i8': c.HEAP8[p>>0] = value; continue; case 'i16': c.HEAP16[p>>1] = value; continue; case 'i32': c.HEAP32[p>>2] = value; continue; @@ -803,7 +808,6 @@ self.WhWasmUtilInstaller = function(target){ /** f64 variant of poke8(). */ target.poke64f = (ptr, value)=>target.poke(ptr, value, 'f64'); - /** Deprecated alias for getMemValue() */ target.getMemValue = target.peek; /** Deprecated alias for peekPtr() */ @@ -1351,7 +1355,7 @@ self.WhWasmUtilInstaller = function(target){ const __argcMismatch = (f,n)=>toss(f+"() requires",n,"argument(s)."); - + /** Looks up a WASM-exported function named fname from target.exports. If found, it is called, passed all remaining @@ -1390,18 +1394,25 @@ self.WhWasmUtilInstaller = function(target){ if(target.bigIntEnabled){ xArg.set('i64', (i)=>BigInt(i)); } - xArg.set('i32', (i)=>(i | 0)); - xArg.set('i16', (i)=>((i | 0) & 0xFFFF)); - xArg.set('i8', (i)=>((i | 0) & 0xFF)); - xArg.set('f32', (i)=>Number(i).valueOf()); - xArg.set('float', xArg.get('f32')); - xArg.set('f64', xArg.get('f32')); - xArg.set('double', xArg.get('f64')); - xArg.set('int', xArg.get('i32')); - xResult.set('*', xArg.get(ptrIR)); - xResult.set('pointer', xArg.get(ptrIR)); - xArg.set('**', xArg.get(ptrIR)); - xResult.set('number', (v)=>Number(v)); + const __xArgPtr = 'i32' === ptrIR + ? ((i)=>(i | 0)) : ((i)=>(BigInt(i) | BigInt(0))); + xArg.set('i32', __xArgPtr ) + .set('i16', (i)=>((i | 0) & 0xFFFF)) + .set('i8', (i)=>((i | 0) & 0xFF)) + .set('f32', (i)=>Number(i).valueOf()) + .set('float', xArg.get('f32')) + .set('f64', xArg.get('f32')) + .set('double', xArg.get('f64')) + .set('int', xArg.get('i32')) + .set('null', (i)=>i) + .set(null, xArg.get('null')) + .set('**', __xArgPtr); + xResult.set('*', __xArgPtr) + .set('pointer', __xArgPtr) + .set('number', (v)=>Number(v)) + .set('void', (v)=>undefined) + .set('null', (v)=>v) + .set(null, xResult.get('null')); { /* Copy certain xArg[...] handlers to xResult[...] and add pointer-style variants of them. */ @@ -1430,15 +1441,17 @@ self.WhWasmUtilInstaller = function(target){ TODO? Permit an Int8Array/Uint8Array and convert it to a string? Would that be too much magic concentrated in one place, ready to - backfire? + backfire? We handle that at the client level in sqlite3 with a + custom argument converter. */ - xArg.set('string', function(v){ + const __xArgString = function(v){ if('string'===typeof v) return target.scopedAllocCString(v); - return v ? xArg.get(ptrIR)(v) : null; - }); - xArg.set('utf8', xArg.get('string')); - xArg.set('pointer', xArg.get('string')); - xArg.set('*', xArg.get('string')); + return v ? __xArgPtr(v) : null; + }; + xArg.set('string', __xArgString); + xArg.set('utf8', __xArgString); + xArg.set('pointer', __xArgString); + xArg.set('*', __xArgString); xResult.set('string', (i)=>target.cstrToJs(i)); xResult.set('utf8', xResult.get('string')); @@ -1452,25 +1465,6 @@ self.WhWasmUtilInstaller = function(target){ try{ return i ? JSON.parse(target.cstrToJs(i)) : null } finally{ target.dealloc(i) } }); - xResult.set('void', (v)=>undefined); - xResult.set('null', (v)=>v); - - if(0){ - /*** - This idea can't currently work because we don't know the - signature for the func and don't have a way for the user to - convey it. To do this we likely need to be able to match - arg/result handlers by a regex, but that would incur an O(N) - cost as we check the regex one at a time. Another use case for - such a thing would be pseudotypes like "int:-1" to say that - the value will always be treated like -1 (which has a useful - case in the sqlite3 bindings). - */ - xArg.set('func-ptr', function(v){ - if(!(v instanceof Function)) return xArg.get(ptrIR); - const f = target.jsFuncToWasm(v, WHAT_SIGNATURE); - }); - } /** Internal-use-only base class for FuncPtrAdapter and potentially @@ -1537,8 +1531,8 @@ self.WhWasmUtilInstaller = function(target){ value. This is only useful for use with "global" functions which do not rely on any state other than this function pointer. If the being-converted function pointer is intended - to be mapped to some sort of state object (e.g. an sqlite3*) - then "context" (see below) is the proper mode. + to be mapped to some sort of state object (e.g. an + `sqlite3*`) then "context" (see below) is the proper mode. - 'context': similar to singleton mode but for a given "context", where the context is a key provided by the user @@ -1698,35 +1692,41 @@ self.WhWasmUtilInstaller = function(target){ (t)=>xResult.get(t) || toss("Result adapter not found:",t); cache.xWrap.convertArg = (t,...args)=>__xArgAdapterCheck(t)(...args); + cache.xWrap.convertArgNoCheck = (t,...args)=>xArg.get(t)(...args); + cache.xWrap.convertResult = (t,v)=>(null===t ? v : (t ? __xResultAdapterCheck(t)(v) : undefined)); + cache.xWrap.convertResultNoCheck = + (t,v)=>(null===t ? v : (t ? xResult.get(t)(v) : undefined)); /** - Creates a wrapper for the WASM-exported function fname. Uses - xGet() to fetch the exported function (which throws on - error) and returns either that function or a wrapper for that + Creates a wrapper for another function which converts the arguments + of the wrapper to argument types accepted by the wrapped function, + then converts the wrapped function's result to another form + for the wrapper. + + The first argument must be one of: + + - A JavaScript function. + - The name of a WASM-exported function. In the latter case xGet() + is used to fetch the exported function, which throws if it's not + found. + - A pointer into the indirect function table. e.g. a pointer + returned from target.installFunction(). + + It returns either the passed-in function or a wrapper for that function which converts the JS-side argument types into WASM-side - types and converts the result type. If the function takes no - arguments and resultType is `null` then the function is returned - as-is, else a wrapper is created for it to adapt its arguments - and result value, as described below. + types and converts the result type. - (If you're familiar with Emscripten's ccall() and cwrap(), this - function is essentially cwrap() on steroids.) - - This function's arguments are: - - - fname: the exported function's name. xGet() is used to fetch - this, so will throw if no exported function is found with that - name. - - - resultType: the name of the result type. A literal `null` means - to return the original function's value as-is (mnemonic: there - is "null" conversion going on). Literal `undefined` or the - string `"void"` mean to ignore the function's result and return - `undefined`. Aside from those two special cases, it may be one - of the values described below or any mapping installed by the - client using xWrap.resultAdapter(). + The second argument, `resultType`, describes the conversion for + the wrapped functions result. A literal `null` or the string + `'null'` both mean to return the original function's value as-is + (mnemonic: there is "null" conversion going on). Literal + `undefined` or the string `"void"` both mean to ignore the + function's result and return `undefined`. Aside from those two + special cases, the `resultType` value may be one of the values + described below or any mapping installed by the client using + xWrap.resultAdapter(). If passed 3 arguments and the final one is an array, that array must contain a list of type names (see below) for adapting the @@ -1740,6 +1740,12 @@ self.WhWasmUtilInstaller = function(target){ xWrap('funcname', 'i32', ['string', 'f64']); ``` + This function enforces that the given list of arguments has the + same arity as the being-wrapped function (as defined by its + `length` property) and it will throw if that is not the case. + Similarly, the created wrapper will throw if passed a differing + argument count. + Type names are symbolic names which map the arguments to an adapter function to convert, if needed, the value before passing it on to WASM or to convert a return result from WASM. The list @@ -1776,6 +1782,10 @@ self.WhWasmUtilInstaller = function(target){ Non-numeric conversions include: + - `null` literal or `"null"` string (args and results): perform + no translation and pass the arg on as-is. This is primarily + useful for results but may have a use or two for arguments. + - `string` or `utf8` (args): has two different semantics in order to accommodate various uses of certain C APIs (e.g. output-style strings)... @@ -1790,9 +1800,9 @@ self.WhWasmUtilInstaller = function(target){ client has already allocated and it's passed on as a WASM pointer. - - `string` or `utf8` (results): treats the result value as a - const C-string, encoded as UTF-8, copies it to a JS string, - and returns that JS string. + - `string` or `utf8` (results): treats the result value as a + const C-string, encoded as UTF-8, copies it to a JS string, + and returns that JS string. - `string:dealloc` or `utf8:dealloc) (results): treats the result value as a non-const UTF-8 C-string, ownership of which has just been @@ -1829,6 +1839,11 @@ self.WhWasmUtilInstaller = function(target){ type conversions are valid for both arguments _and_ result types as they often have different memory ownership requirements. + Design note: the ability to pass in a JS function as the first + argument is of relatively limited use, primarily for testing + argument and result converters. JS functions, by and large, will + not want to deal with C-type arguments. + TODOs: - Figure out how/whether we can (semi-)transparently handle @@ -1849,14 +1864,21 @@ self.WhWasmUtilInstaller = function(target){ abstracting it into this API (and taking on the associated costs) may well not make good sense. */ - target.xWrap = function(fname, resultType, ...argTypes){ + target.xWrap = function(fArg, resultType, ...argTypes){ if(3===arguments.length && Array.isArray(arguments[2])){ argTypes = arguments[2]; } - const xf = target.xGet(fname); - if(argTypes.length!==xf.length) __argcMismatch(fname, xf.length); + if(target.isPtr(fArg)){ + fArg = target.functionEntry(fArg) + || toss("Function pointer not found in WASM function table."); + } + const fIsFunc = (fArg instanceof Function); + const xf = fIsFunc ? fArg : target.xGet(fArg); + if(fIsFunc) fArg = xf.name || 'unnamed function'; + if(argTypes.length!==xf.length) __argcMismatch(fArg, xf.length); if((null===resultType) && 0===xf.length){ - /* Func taking no args with an as-is return. We don't need a wrapper. */ + /* Func taking no args with an as-is return. We don't need a wrapper. + We forego the argc check here, though. */ return xf; } /*Verify the arg type conversions are valid...*/; @@ -1869,11 +1891,11 @@ self.WhWasmUtilInstaller = function(target){ if(0===xf.length){ // No args to convert, so we can create a simpler wrapper... return (...args)=>(args.length - ? __argcMismatch(fname, xf.length) + ? __argcMismatch(fArg, xf.length) : cxw.convertResult(resultType, xf.call(null))); } return function(...args){ - if(args.length!==xf.length) __argcMismatch(fname, xf.length); + if(args.length!==xf.length) __argcMismatch(fArg, xf.length); const scope = target.scopedAllocPush(); try{ /* @@ -1891,8 +1913,8 @@ self.WhWasmUtilInstaller = function(target){ and what those arguments are, is _not_ part of the public interface and is _not_ stable. */ - for(const i in args) args[i] = cxw.convertArg(argTypes[i], args[i], i, args); - return cxw.convertResult(resultType, xf.apply(null,args)); + for(const i in args) args[i] = cxw.convertArgNoCheck(argTypes[i], args[i], i, args); + return cxw.convertResultNoCheck(resultType, xf.apply(null,args)); }finally{ target.scopedAllocPop(scope); } @@ -1984,14 +2006,13 @@ self.WhWasmUtilInstaller = function(target){ /** Functions like xCall() but performs argument and result type - conversions as for xWrap(). The first argument is the name of the - exported function to call. The 2nd its the name of its result - type, as documented for xWrap(). The 3rd is an array of argument - type name, as documented for xWrap() (use a falsy value or an - empty array for nullary functions). The 4th+ arguments are - arguments for the call, with the special case that if the 4th - argument is an array, it is used as the arguments for the - call. Returns the converted result of the call. + conversions as for xWrap(). The first, second, and third + arguments are as documented for xWrap(), except that the 3rd + argument may be either a falsy value or empty array to represent + nullary functions. The 4th+ arguments are arguments for the call, + with the special case that if the 4th argument is an array, it is + used as the arguments for the call. Returns the converted result + of the call. This is just a thin wrapper around xWrap(). If the given function is to be called more than once, it's more efficient to use @@ -2000,9 +2021,9 @@ self.WhWasmUtilInstaller = function(target){ arguably more efficient because it will hypothetically free the wrapper function quickly. */ - target.xCallWrapped = function(fname, resultType, argTypes, ...args){ + target.xCallWrapped = function(fArg, resultType, argTypes, ...args){ if(Array.isArray(arguments[3])) args = arguments[3]; - return target.xWrap(fname, resultType, argTypes||[]).apply(null, args||[]); + return target.xWrap(fArg, resultType, argTypes||[]).apply(null, args||[]); }; /** diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index bef34a0ba5..eb014d7b51 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -539,7 +539,7 @@ self.sqlite3InitModule = sqlite3InitModule; } w.dealloc(m); } - + // isPtr32() { const ip = w.isPtr32; @@ -743,6 +743,65 @@ self.sqlite3InitModule = sqlite3InitModule; .assert('HI' === cj(new Uint8Array([72, 73]))); }); + // jsFuncToWasm() + { + const fsum3 = (x,y,z)=>x+y+z; + fw = w.jsFuncToWasm('i(iii)', fsum3); + T.assert(fw instanceof Function) + .assert( fsum3 !== fw ) + .assert( 3 === fw.length ) + .assert( 6 === fw(1,2,3) ); + T.mustThrowMatching( ()=>w.jsFuncToWasm('x()', function(){}), + 'Invalid signature letter: x'); + } + + // xWrap(Function,...) + { + let fp; + try { + const fmy = function fmy(i,s,d){ + if(fmy.debug) log("fmy(",...arguments,")"); + T.assert( 3 === i ) + .assert( w.isPtr(s) ) + .assert( w.cstrToJs(s) === 'a string' ) + .assert( T.eqApprox(1.2, d) ); + return w.allocCString("hi"); + }; + fmy.debug = false; + const xwArgs = ['string:dealloc', ['i32', 'string', 'f64']]; + fw = w.xWrap(fmy, ...xwArgs); + const fmyArgs = [3, 'a string', 1.2]; + let rc = fw(...fmyArgs); + T.assert( 'hi' === rc ); + if(0){ + /* Retain this as a "reminder to self"... + + This extra level of indirection does not work: the + string argument is ending up as a null in fmy() but + the numeric arguments are making their ways through + + What's happening is: installFunction() is creating a + WASM-compatible function instance. When we pass a JS string + into there it's getting coerced into `null` before being passed + on to the lower-level wrapper. + */ + fmy.debug = true; + fp = wasm.installFunction('i(isd)', fw); + fw = w.functionEntry(fp); + rc = fw(...fmyArgs); + log("rc =",rc); + T.assert( 'hi' === rc ); + // Similarly, this does not work: + //let fpw = w.xWrap(fp, null, [null,null,null]); + //rc = fpw(...fmyArgs); + //log("rc =",rc); + //T.assert( 'hi' === rc ); + } + }finally{ + wasm.uninstallFunction(fp); + } + } + if(haveWasmCTests()){ if(!sqlite3.config.useStdAlloc){ fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:dealloc',['i32']); @@ -768,7 +827,7 @@ self.sqlite3InitModule = sqlite3InitModule; }); } } - } + }/*xWrap()*/ }/*WhWasmUtil*/) //////////////////////////////////////////////////////////////////// @@ -997,7 +1056,6 @@ self.sqlite3InitModule = sqlite3InitModule; P.restore(stack); } }/*pstack tests*/) - //////////////////////////////////////////////////////////////////// ;/*end of C/WASM utils checks*/ diff --git a/manifest b/manifest index eacaf992fb..a0be8ba9e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssqlite3.capi\sJS\sbindings\sfor\sthe\ssqlite3session_...(),\ssqlite3changeset_...()\sand\ssqlite3changegroup_...()\sAPIs,\snoting\sthat\sthey\sare\scompletely\suntested.\sAside\sfrom\smissing\stests,\sthese\sbindings\sreveal\sa\sslight\sstring-argument-type\sshortcoming\sin\sthe\scallback\sfunction\spointer\s"reverse\sbinding"\swhich\sshould\sideally\sbe\sresolved\sbefore\spublishing\sthem. -D 2022-12-23T14:11:54.508 +C Internal\scleanups\sand\sminor\sspeed\soptimizations\sin\sthe\ssqlite3.wasm.xWrap()\sinfrastructure. +D 2022-12-23T18:14:36.766 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js af85d9a09fa79847d08279be0f61978ecc3bed893c88003f4a85d8bd204e6b5a +F ext/wasm/common/whwasmutil.js ccfd4addd60f0c3f02ee1669c4e5c8935ca770ed7b737ea3e9e82cc6505576c8 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js c45c46cdae1949d426ee12a736087ab180beacc2a20cd829f9052b957adf9ac9 +F ext/wasm/tester1.c-pp.js 4202e7ec525445386f29612ddf1365348edd1f6002b8b21721c954b9569b756a F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 -R 042a575edf17a004d3f3655705629da7 +P 0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d +R 01a5a3416aa00dbf975dac1dad0558b8 U stephan -Z 81bf3460fe50c1e6a01aac07ed8bed30 +Z fd750e2a8255c013dd9faba040bbeb23 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index aa150a668b..8d218fa6ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d \ No newline at end of file +c4dab53b8ea3401abd57671b8f3cb39fa4431b864d4c4e14ae24592f8d4cba0a \ No newline at end of file From 3494ec15e574fe752dbbca78cf2d21156f7da68b Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 15:14:10 +0000 Subject: [PATCH 4/8] Update the session-related JS bindings to account for today's internal API changes. FossilOrigin-Name: be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 --- ext/wasm/api/sqlite3-api-glue.js | 39 +++++++++++++++++++------------- manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index fc5e2823d6..91be75b81f 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -317,16 +317,23 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ // Add session/changeset APIs... if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){ /* ACHTUNG: 2022-12-23: the session/changeset API bindings are - COMPLETELY UNTESTED. Additionally, the callback-taking APIs - have a shortcoming which will make using those which take - string-type arguments more painful than it should be. How best - to resolve that, such that we can perform the same type conversions - as we do when binding in "the other direction," is as yet - undetermined. + COMPLETELY UNTESTED. */ + /** + FuncPtrAdapter options for session-related callbacks with the + native signature "i(ps)". This proxy converts the 2nd argument + from a C string to a JS string before passing the arguments on + to the client-provided JS callback. */ - /* TODO: we need hand-written wrappers to adapt callbacks which - take string arguments. Or we need to find a way to do this sort - of reverse-binding which includes type conversions. */ + const __ipsProxy = { + signature: 'i(ps)', + callProxy:(callback)=>{ + return (p,s)=>{ + try{return callback(p, wasm.cstrToJs(s)) | 0} + catch(e){return e.resultCode || capi.SQLITE_ERROR} + } + } + }; + wasm.bindingSignatures.int64.push(...[ ['sqlite3changegroup_add', 'int', ['sqlite3_changegroup*', 'int', 'void*']], ['sqlite3changegroup_add_strm', 'int', [ @@ -349,7 +356,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3changeset_apply', 'int', [ 'sqlite3*', 'int', 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -363,7 +370,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }), 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -373,7 +380,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3changeset_apply_v2', 'int', [ 'sqlite3*', 'int', 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -384,7 +391,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3changeset_apply_v2', 'int', [ 'sqlite3*', 'int', 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -398,7 +405,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }), 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -487,8 +494,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3session_table_filter', undefined, [ 'sqlite3_session*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', - contextKey: (argIndex,argv)=>argv[0/* (sqlite3_session*) */] + name: 'xFilter', ...__ipsProxy, + contextKey: (argv,argIndex)=>argv[0/* (sqlite3_session*) */] }), '*' ]] diff --git a/manifest b/manifest index 8b68df83ea..841003c821 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\sinto\swasm-session-api\sbranch. -D 2022-12-25T14:13:52.379 +C Update\sthe\ssession-related\sJS\sbindings\sto\saccount\sfor\stoday's\sinternal\sAPI\schanges. +D 2022-12-25T15:14:10.329 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 171657a8c758cba72d903b20b42c72a523915ca03c8d652339bf41f5f1da2f09 +F ext/wasm/api/sqlite3-api-glue.js f22d7bc226b6b8b1f8399cdcc547ad3289b49f39722c91301fe07e529148a94f F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6cdb036d8e8c5ddb0c6578aeefe318e74d7a90228e57b9f9047057dae3252963 8e3d4f6294037396e388ec21abb18bf0201a6bec6ff004730cc5d11b705a6d2b -R 81fe514e1af16b08edf276165dc4ebe1 +P 7f8f1acd82be7dc2eb2147d96299b1b443e86774dfe0b0a8d32669a0500fc9c6 +R dfeb1d551c8453a8d3a795c7dad85108 U stephan -Z 68ce3f310d94edded8b970aa4257758a +Z 7d17f1f03aff9dd128f571dc7f5c762d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 29353fc4d9..e8d64eedfa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f8f1acd82be7dc2eb2147d96299b1b443e86774dfe0b0a8d32669a0500fc9c6 \ No newline at end of file +be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 \ No newline at end of file From 8b5a5ef030182a54e4752043c5e6bdf2db6d6951 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 15:28:19 +0000 Subject: [PATCH 5/8] Add the address of the associated db handle to the sqlite3_trace_v2() output originating from sqlite3.oo1.DB's trace flag. FossilOrigin-Name: 0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 --- ext/wasm/api/sqlite3-api-oo1.js | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 16f5f00b15..1823773dec 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -72,7 +72,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.installFunction('i(ippp)', function(t,c,p,x){ if(capi.SQLITE_TRACE_STMT===t){ // x == SQL, p == sqlite3_stmt* - console.log("SQL TRACE #"+(++this.counter), + console.log("SQL TRACE #"+(++this.counter)+' via sqlite3@'+c+':', wasm.cstrToJs(x)); } }.bind({counter: 0})); @@ -161,7 +161,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ capi.sqlite3_extended_result_codes(pDb, 1); if(flagsStr.indexOf('t')>=0){ capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT, - __dbTraceToConsole, 0); + __dbTraceToConsole, pDb); } }catch( e ){ if( pDb ) capi.sqlite3_close_v2(pDb); diff --git a/manifest b/manifest index 841003c821..ef1186091e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\ssession-related\sJS\sbindings\sto\saccount\sfor\stoday's\sinternal\sAPI\schanges. -D 2022-12-25T15:14:10.329 +C Add\sthe\saddress\sof\sthe\sassociated\sdb\shandle\sto\sthe\ssqlite3_trace_v2()\soutput\soriginating\sfrom\ssqlite3.oo1.DB's\strace\sflag. +D 2022-12-25T15:28:19.113 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js f22d7bc226b6b8b1f8399cdcc547ad3289b49f39722c91301fe07e529148a94f -F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b +F ext/wasm/api/sqlite3-api-oo1.js ae4f6950913b4703b767f640a533675b45e9e6c462bf01e357cec16bc68943e2 F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f8f1acd82be7dc2eb2147d96299b1b443e86774dfe0b0a8d32669a0500fc9c6 -R dfeb1d551c8453a8d3a795c7dad85108 +P be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 +R a0850be6b0937570f1f7baa999a6a514 U stephan -Z 7d17f1f03aff9dd128f571dc7f5c762d +Z c3cd9380ad4a7408eae4565bc713502d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e8d64eedfa..82c4e532fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 \ No newline at end of file +0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 \ No newline at end of file From 031ee6b9dabe7711c5ec7cfd91f7bef20cb7432e Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 16:20:05 +0000 Subject: [PATCH 6/8] Remove duplicated JS binding of sqlite3changeset_apply_v2(). FossilOrigin-Name: 2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 --- ext/wasm/api/sqlite3-api-glue.js | 10 ---------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 91be75b81f..7d4d888d76 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -388,16 +388,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ 'void*', '**', 'int*', 'int' ]], - ['sqlite3changeset_apply_v2', 'int', [ - 'sqlite3*', 'int', 'void*', - new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', bindScope: 'transient', ...__ipsProxy - }), - new wasm.xWrap.FuncPtrAdapter({ - name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' - }), - 'void*', '**', 'int*', 'int' - ]], ['sqlite3changeset_apply_v2_strm', 'int', [ 'sqlite3*', new wasm.xWrap.FuncPtrAdapter({ diff --git a/manifest b/manifest index ef1186091e..93bd6a9a83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\saddress\sof\sthe\sassociated\sdb\shandle\sto\sthe\ssqlite3_trace_v2()\soutput\soriginating\sfrom\ssqlite3.oo1.DB's\strace\sflag. -D 2022-12-25T15:28:19.113 +C Remove\sduplicated\sJS\sbinding\sof\ssqlite3changeset_apply_v2(). +D 2022-12-25T16:20:05.864 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js f22d7bc226b6b8b1f8399cdcc547ad3289b49f39722c91301fe07e529148a94f +F ext/wasm/api/sqlite3-api-glue.js fe8a0c30d906e4f14be26a2abdad5d84aa901eeb594f76c8050cb4df4f746a5d F ext/wasm/api/sqlite3-api-oo1.js ae4f6950913b4703b767f640a533675b45e9e6c462bf01e357cec16bc68943e2 F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 -R a0850be6b0937570f1f7baa999a6a514 +P 0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 +R 7b14429320eea0000f7897f56a599155 U stephan -Z c3cd9380ad4a7408eae4565bc713502d +Z c6f737ca9a33ea9873dd8c76d61cfde2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 82c4e532fb..8c99823063 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 \ No newline at end of file +2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 \ No newline at end of file From 7d59d90a5b9dc56f5a19fe9a24be2500af664013 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 20:05:11 +0000 Subject: [PATCH 7/8] Add sqlite3.wasm.irSizeof() and extend certain allocation functions to make use of it. FossilOrigin-Name: 1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 --- ext/wasm/api/sqlite3-api-prologue.js | 17 +++++++++++++++-- ext/wasm/common/whwasmutil.js | 19 +++++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 7804c04589..aafe1dd08b 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1020,12 +1020,20 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( to the memory. On error, returns throws a WasmAllocError. The memory must eventually be released using restore(). + If n is a string, it must be a WASM "IR" value in the set + accepted by wasm.irSizeof(), which is mapped to the size of + that data type. If passed a string not in that set, it throws a + WasmAllocError. + This method always adjusts the given value to be a multiple of 8 bytes because failing to do so can lead to incorrect results when reading and writing 64-bit values from/to the WASM heap. Similarly, the returned address is always 8-byte aligned. */ - alloc: (n)=>{ + alloc: function(n){ + if('string'===typeof n && !(n = wasm.irSizeof(n))){ + WasmAllocError.toss("Invalid value for pstack.alloc(",arguments[0],")"); + } return wasm.exports.sqlite3_wasm_pstack_alloc(n) || WasmAllocError.toss("Could not allocate",n, "bytes from the pstack."); @@ -1035,6 +1043,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( returns the addresses as an array of n element, each holding the address of one chunk. + sz may optionally be an IR string accepted by wasm.irSizeof(). + Throws a WasmAllocError if allocation fails. Example: @@ -1043,7 +1053,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( const [p1, p2, p3] = wasm.pstack.allocChunks(3,4); ``` */ - allocChunks: (n,sz)=>{ + allocChunks: function(n,sz){ + if('string'===typeof sz && !(sz = wasm.irSizeof(sz))){ + WasmAllocError.toss("Invalid size value for allocChunks(",arguments[1],")"); + } const mem = wasm.pstack.alloc(n * sz); const rc = []; let i = 0, offset = 0; diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index c296a946b9..e6f32abfae 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -246,6 +246,25 @@ self.WhWasmUtilInstaller = function(target){ cache.utf8Decoder = new TextDecoder(); cache.utf8Encoder = new TextEncoder('utf-8'); + /** + For the given IR-like string in the set ('i8', 'i16', 'i32', + 'f32', 'float', 'i64', 'f64', 'double', '*'), or any string value + ending in '*', returns the sizeof for that value + (target.ptrSizeof in the latter case). For any other value, it + returns the undefined value. + */ + target.irSizeof = (n)=>{ + switch(n){ + case 'i8': return 1; + case 'i16': return 2; + case 'i32': case 'f32': case 'float': return 4; + case 'i64': case 'f64': case 'double': return 8; + case '*': return ptrSizeof; + default: + return (''+n).endsWith('*') ? ptrSizeof : undefined; + } + }; + /** If (cache.heapSize !== cache.memory.buffer.byteLength), i.e. if the heap has grown since the last call, updates cache.HEAPxyz. diff --git a/manifest b/manifest index 93bd6a9a83..8ff3505e92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sduplicated\sJS\sbinding\sof\ssqlite3changeset_apply_v2(). -D 2022-12-25T16:20:05.864 +C Add\ssqlite3.wasm.irSizeof()\sand\sextend\scertain\sallocation\sfunctions\sto\smake\suse\sof\sit. +D 2022-12-25T20:05:11.134 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -505,7 +505,7 @@ F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a9578430388 F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js fe8a0c30d906e4f14be26a2abdad5d84aa901eeb594f76c8050cb4df4f746a5d F ext/wasm/api/sqlite3-api-oo1.js ae4f6950913b4703b767f640a533675b45e9e6c462bf01e357cec16bc68943e2 -F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 +F ext/wasm/api/sqlite3-api-prologue.js 72e2b66daf1f5ea7b6a8477c4fe86493925a067cfa0b156a339589e653446920 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 495cdffe8a6107608412ee57cdad79267f14a56e6b7825b9dc30c8ccfb02c87b +F ext/wasm/common/whwasmutil.js a94f776bd3afcfc73283aad2bb0821ddf8e77f687a0d7ee84d14d2a138d78636 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 -R 7b14429320eea0000f7897f56a599155 +P 2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 +R 63f0c28ba499a3e86a80a83d5b02806d U stephan -Z c6f737ca9a33ea9873dd8c76d61cfde2 +Z e2479a6e1c7cf91263ea3378ad83cfc4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8c99823063..f118531ec6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 \ No newline at end of file +1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 \ No newline at end of file From 9d61db1944238d35ee00cefe0b4bfb7ac291e36b Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 20:22:20 +0000 Subject: [PATCH 8/8] Add basic session API JS tests. FossilOrigin-Name: 64e032602cf420851c8029603c76f5512000d1c9a40fa7a545528d69d6d1d4cc --- ext/wasm/tester1.c-pp.js | 88 +++++++++++++++++++++++++++++++++++++--- manifest | 12 +++--- manifest.uuid | 2 +- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index a9b29729b8..9655cd8572 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1010,7 +1010,12 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(P.quota >= 4096) .assert(remaining === P.quota) .mustThrowMatching(()=>P.alloc(0), isAllocErr) - .mustThrowMatching(()=>P.alloc(-1), isAllocErr); + .mustThrowMatching(()=>P.alloc(-1), isAllocErr) + .mustThrowMatching( + ()=>P.alloc('i33'), + (e)=>e instanceof sqlite3.WasmAllocError + ); + ; let p1 = P.alloc(12); T.assert(p1 === stack - 16/*8-byte aligned*/) .assert(P.pointer === p1); @@ -1029,7 +1034,7 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(P.pointer === stack); try { - const [p1, p2, p3] = P.allocChunks(3,4); + const [p1, p2, p3] = P.allocChunks(3,'i32'); T.assert(P.pointer === stack-16/*always rounded to multiple of 8*/) .assert(p2 === p1 + 4) .assert(p3 === p2 + 4); @@ -1143,7 +1148,7 @@ self.sqlite3InitModule = sqlite3InitModule; } } }; - + T.assert(wasm.isPtr(db.pointer)) .mustThrowMatching(()=>db.pointer=1, /read-only/) .assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1)) @@ -1183,7 +1188,7 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(0 === rc); const stack = wasm.pstack.pointer; try { - const [pCur, pHi] = wasm.pstack.allocChunks(2,8); + const [pCur, pHi] = wasm.pstack.allocChunks(2,'i64'); rc = capi.sqlite3_db_status(this.db, capi.SQLITE_DBSTATUS_LOOKASIDE_USED, pCur, pHi, 0); T.assert(0===rc); @@ -1729,7 +1734,7 @@ self.sqlite3InitModule = sqlite3InitModule; // sqlite3_result_xyz() and return undefined. Both are // functionally equivalent. } - }); + }); T.assert(18===db.selectValue('select summerN(1,8,9), summerN(2,3,4)')); T.mustThrowMatching(()=>{ db.createFunction('nope',{ @@ -1856,7 +1861,6 @@ self.sqlite3InitModule = sqlite3InitModule; .assert('select 2;' === rc[1]) .assert('-- empty\n; select 3' === rc[2] /* Strange but true. */); - T.mustThrowMatching(()=>{ db.exec({sql:'', returnValue: 'nope'}); }, /^Invalid returnValue/); @@ -2632,6 +2636,78 @@ self.sqlite3InitModule = sqlite3InitModule; }/*OPFS util sanity checks*/) ;/* end OPFS tests */ + T.g('Session API') + .t({ + name: 'Session API sanity checks', + predicate: ()=>!!capi.sqlite3changegroup_add, + test: function(sqlite3){ + const db1 = new sqlite3.oo1.DB(), db2 = new sqlite3.oo1.DB(); + const sqlInit = [ + "create table t(rowid INTEGER PRIMARY KEY,a,b); ", + "insert into t(rowid,a,b) values", + "(1,'a1','b1'),", + "(2,'a2','b2'),", + "(3,'a3','b3');" + ].join(''); + db1.exec(sqlInit); + db2.exec(sqlInit); + T.assert(3 === db1.selectValue("select count(*) from t")) + .assert('b3' === db1.selectValue('select b from t where rowid=3')); + const stackPtr = wasm.pstack.pointer; + try{ + let ppOut = wasm.pstack.allocPtr(); + let rc = capi.sqlite3session_create(db1, "main", ppOut); + T.assert(0===rc); + let pSession = wasm.peekPtr(ppOut); + T.assert(pSession && wasm.isPtr(pSession)); + if(1){ + capi.sqlite3session_table_filter(pSession, (pCtx, tbl)=>{ + T.assert('t' === tbl).assert( 99 === pCtx ); + return 1; + }, 99); + }else{ + rc = capi.sqlite3session_attach(pSession, "t"); + T.assert( 0 === rc ); + } + db1.exec([ + "update t set b='bTwo' where rowid=2;", + "update t set a='aThree' where rowid=3;", + "delete from t where rowid=1;", + "insert into t(rowid,a,b) values(4,'a4','b4')" + ]); + T.assert('bTwo' === db1.selectValue("select b from t where rowid=2")) + .assert(undefined === db1.selectValue('select a from t where rowid=1')) + .assert('b4' === db1.selectValue('select b from t where rowid=4')); + + let pnChanges = wasm.pstack.alloc('i32'), + ppChanges = wasm.pstack.allocPtr(); + rc = capi.sqlite3session_changeset(pSession, pnChanges, ppChanges); + T.assert( 0 === rc ); + capi.sqlite3session_delete(pSession); + pSession = 0; + const pChanges = wasm.peekPtr(ppChanges), + nChanges = wasm.peek32(pnChanges); + T.assert( pChanges && wasm.isPtr( pChanges ) ).assert( nChanges > 0 ); + pnChanges = ppChanges = 0; + //log("pnChanges =", pnChanges, wasm.peek32(pnChanges), '@', pChanges); + rc = capi.sqlite3changeset_apply( + db2, nChanges, pChanges, 0, (pCtx, eConflict, pIter)=>{ + return pCtx ? 1 : 0 + }, 1 + ); + wasm.dealloc( pChanges ); + T.assert( 0 === rc ) + .assert( 3 === db2.selectValue('select count(*) from t')) + .assert( 'b4' === db2.selectValue('select b from t where rowid=4') ); + }finally{ + wasm.pstack.restore(stackPtr); + db1.close(); + db2.close(); + } + } + }) + ;/*end of session API group*/; + //////////////////////////////////////////////////////////////////////// log("Loading and initializing sqlite3 WASM module..."); if(!self.sqlite3InitModule && !isUIThread()){ diff --git a/manifest b/manifest index 8ff3505e92..4de86c1325 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssqlite3.wasm.irSizeof()\sand\sextend\scertain\sallocation\sfunctions\sto\smake\suse\sof\sit. -D 2022-12-25T20:05:11.134 +C Add\sbasic\ssession\sAPI\sJS\stests. +D 2022-12-25T20:22:20.918 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 47190277040a6163716c02d11930dc4f028d44a6fcdacb10303010f239ce0a6c +F ext/wasm/tester1.c-pp.js a690f82c02d2b0531bad264054a276d09d274487fd1f8aac6bab24f7cfedaa6f F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 -R 63f0c28ba499a3e86a80a83d5b02806d +P 1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 +R e7bca9ee95dfee32728e67001af3a1d6 U stephan -Z e2479a6e1c7cf91263ea3378ad83cfc4 +Z 1d08930538afdb25a0799e1e3a67b3c1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f118531ec6..3d55a2ae03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 \ No newline at end of file +64e032602cf420851c8029603c76f5512000d1c9a40fa7a545528d69d6d1d4cc \ No newline at end of file