Add JS wrapper for sqlite3_exec() which knows how to handle a JS callback. Add some console.error() reporting of module-load failures, as they otherwise often get silently swallowed up by the loader's mechanisms. Add 'flexible-string' JS-to-WASM argument converter which performs more X-to-string conversions than the 'string' arg converter does.

FossilOrigin-Name: 96818aa83f4ccc574f558231249ecbdd39763b4351cf4cf6d33f53774a3ee5e6
This commit is contained in:
stephan 2022-09-30 20:35:37 +00:00
parent d18f1bbfe0
commit e67a0f40e4
8 changed files with 227 additions and 73 deletions

View File

@ -15,7 +15,6 @@
if(!originalInit){ if(!originalInit){
throw new Error("Expecting self.sqlite3InitModule to be defined by the Emscripten build."); throw new Error("Expecting self.sqlite3InitModule to be defined by the Emscripten build.");
} }
self.sqlite3InitModule.ready = originalInit.ready;
self.sqlite3InitModule = (...args)=>{ self.sqlite3InitModule = (...args)=>{
//console.warn("Using replaced sqlite3InitModule()",self.location); //console.warn("Using replaced sqlite3InitModule()",self.location);
return originalInit(...args).then((EmscriptenModule)=>{ return originalInit(...args).then((EmscriptenModule)=>{
@ -35,7 +34,11 @@
const f = EmscriptenModule.sqlite3.asyncPostInit; const f = EmscriptenModule.sqlite3.asyncPostInit;
delete EmscriptenModule.sqlite3.asyncPostInit; delete EmscriptenModule.sqlite3.asyncPostInit;
return f(); return f();
}).catch((e)=>{
console.error("Exception loading sqlite3 module:",e);
throw e;
}); });
}; };
self.sqlite3InitModule.ready = originalInit.ready;
//console.warn("Replaced sqlite3InitModule()"); //console.warn("Replaced sqlite3InitModule()");
})(); })();

View File

@ -46,6 +46,9 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build
let sqlite3; let sqlite3;
try{ try{
sqlite3 = self.sqlite3ApiBootstrap(); sqlite3 = self.sqlite3ApiBootstrap();
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
}finally{ }finally{
delete self.sqlite3ApiBootstrap; delete self.sqlite3ApiBootstrap;
if(rmApiConfig) delete self.sqlite3ApiConfig; if(rmApiConfig) delete self.sqlite3ApiConfig;

View File

@ -33,20 +33,27 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
to a C-style sqlite3_xxx function which takes an `sqlite3*` to a C-style sqlite3_xxx function which takes an `sqlite3*`
argument. argument.
*/ */
const oldP = wasm.xWrap.argAdapter('pointer'); const xPointer = wasm.xWrap.argAdapter('pointer');
const adapter = function(v){ const adapter = function(v){
if(v && 'object'===typeof v && v.constructor){ if(v && v.constructor){
const x = v.pointer; const x = v.pointer;
if(Number.isInteger(x)) return x; if(Number.isInteger(x)) return x;
else toss("Invalid (object) type for pointer-type argument."); else toss("Invalid (object) type for .pointer-type argument.");
} }
return oldP(v); return xPointer(v);
}; };
wasm.xWrap.argAdapter('.pointer', adapter); wasm.xWrap.argAdapter('.pointer', adapter);
} /* ".pointer" xWrap() argument adapter */ } /* ".pointer" xWrap() argument adapter */
// WhWasmUtil.xWrap() bindings... if(1){/* Convert Arrays and certain TypedArrays to strings for
{ 'flexible-string'-type arguments */
const xString = wasm.xWrap.argAdapter('string');
wasm.xWrap.argAdapter(
'flexible-string', (v)=>xString(util.arrayToString(v))
);
}
if(1){// WhWasmUtil.xWrap() bindings...
/** /**
Add some descriptive xWrap() aliases for '*' intended to Add some descriptive xWrap() aliases for '*' intended to
(A) initially improve readability/correctness of capi.signatures (A) initially improve readability/correctness of capi.signatures
@ -107,51 +114,139 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*xWrap() bindings*/; }/*xWrap() bindings*/;
/** /**
Scope-local holder of the two impls of sqlite3_prepare_v2/v3(). Internal helper to assist in validating call argument counts in
the hand-written sqlite3_xyz() wrappers. We do this only for
consistency with non-special-case wrappings.
*/ */
const __prepare = Object.create(null); const __dbArgcMismatch = (pDb,f,n)=>{
/** return sqlite3.util.sqlite3_wasm_db_error(pDb, capi.SQLITE_MISUSE,
This binding expects a JS string as its 2nd argument and f+"() requires "+n+" argument"+
null as its final argument. In order to compile multiple (1===n?'':'s')+".");
statements from a single string, the "full" impl (see
below) must be used.
*/
__prepare.basic = wasm.xWrap('sqlite3_prepare_v3',
"int", ["sqlite3*", "string",
"int"/*ignored for this impl!*/,
"int", "**",
"**"/*MUST be 0 or null or undefined!*/]);
/**
Impl which requires that the 2nd argument be a pointer
to the SQL string, instead of being converted to a
string. This variant is necessary for cases where we
require a non-NULL value for the final argument
(exec()'ing multiple statements from one input
string). For simpler cases, where only the first
statement in the SQL string is required, the wrapper
named sqlite3_prepare_v2() is sufficient and easier to
use because it doesn't require dealing with pointers.
*/
__prepare.full = wasm.xWrap('sqlite3_prepare_v3',
"int", ["sqlite3*", "*", "int", "int",
"**", "**"]);
/* Documented in the api object's initializer. */
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
if(util.isSQLableTypedArray(sql)) sql = util.typedArrayToString(sql);
switch(typeof sql){
case 'string': return __prepare.basic(pDb, sql, -1, prepFlags, ppStmt, null);
case 'number': return __prepare.full(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail);
default:
return util.sqlite3_wasm_db_error(
pDb, capi.SQLITE_MISUSE,
"Invalid SQL argument type for sqlite3_prepare_v2/v3()."
);
}
}; };
capi.sqlite3_prepare_v2 = /**
(pDb, sql, sqlLen, ppStmt, pzTail)=>capi.sqlite3_prepare_v3(pDb, sql, sqlLen, 0, ppStmt, pzTail); Helper for flexible-string conversions which require a
byte-length counterpart argument. Passed a value and its
ostensible length, this function returns [V,N], where V
is either v or a transformed copy of v and N is either n,
-1, or the byte length of v (if it's a byte array).
*/
const __flexiString = function(v,n){
if('string'===typeof v){
n = -1;
}else if(util.isSQLableTypedArray(v)){
n = v.byteLength;
v = util.typedArrayToString(v);
}else if(Array.isArray(v)){
v = v.join('');
n = -1;
}
return [v, n];
};
if(1){/* Special-case handling of sqlite3_exec() */
const __exec = wasm.xWrap("sqlite3_exec", "int",
["sqlite3*", "flexible-string", "*", "*", "**"]);
/* Documented in the api object's initializer. */
capi.sqlite3_exec = function(pDb, sql, callback, pVoid, pErrMsg){
if(5!==arguments.length){
return __dbArgcMismatch(pDb,"sqlite3_exec",5);
}else if('function' !== typeof callback){
return __exec(pDb, sql, callback, pVoid, pErrMsg);
}
/* Wrap the callback in a WASM-bound function and convert the callback's
`(char**)` arguments to arrays of strings... */
const wasm = capi.wasm;
const cbwrap = function(pVoid, nCols, pColVals, pColNames){
let rc = capi.SQLITE_ERROR;
try {
let aVals = [], aNames = [], i = 0, offset = 0;
for( ; i < nCols; offset += (wasm.ptrSizeof * ++i) ){
aVals.push( wasm.cstringToJs(wasm.getPtrValue(pColVals + offset)) );
aNames.push( wasm.cstringToJs(wasm.getPtrValue(pColNames + offset)) );
}
rc = callback(pVoid, nCols, aVals, aNames) | 0;
/* The first 2 args of the callback are useless for JS but
we want the JS mapping of the C API to be as close to the
C API as possible. */
}catch(e){
/* If we set the db error state here, the higher-level exec() call
replaces it with its own, so we have no way of reporting the
exception message except the console. We must not propagate
exceptions through the C API. */
}
return rc;
};
let pFunc, rc;
try{
pFunc = wasm.installFunction("ipipp", cbwrap);
rc = __exec(pDb, sql, pFunc, pVoid, pErrMsg);
}catch(e){
rc = util.sqlite3_wasm_db_error(pDb, capi.SQLITE_ERROR,
"Error running exec(): "+e.message);
}finally{
if(pFunc) wasm.uninstallFunction(pFunc);
}
return rc;
};
}/*sqlite3_exec() proxy*/;
if(1){/* Special-case handling of sqlite3_prepare_v2() and
sqlite3_prepare_v3() */
/**
Scope-local holder of the two impls of sqlite3_prepare_v2/v3().
*/
const __prepare = Object.create(null);
/**
This binding expects a JS string as its 2nd argument and
null as its final argument. In order to compile multiple
statements from a single string, the "full" impl (see
below) must be used.
*/
__prepare.basic = wasm.xWrap('sqlite3_prepare_v3',
"int", ["sqlite3*", "string",
"int"/*ignored for this impl!*/,
"int", "**",
"**"/*MUST be 0 or null or undefined!*/]);
/**
Impl which requires that the 2nd argument be a pointer
to the SQL string, instead of being converted to a
string. This variant is necessary for cases where we
require a non-NULL value for the final argument
(exec()'ing multiple statements from one input
string). For simpler cases, where only the first
statement in the SQL string is required, the wrapper
named sqlite3_prepare_v2() is sufficient and easier to
use because it doesn't require dealing with pointers.
*/
__prepare.full = wasm.xWrap('sqlite3_prepare_v3',
"int", ["sqlite3*", "*", "int", "int",
"**", "**"]);
/* Documented in the api object's initializer. */
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
if(6!==arguments.length){
return __dbArgcMismatch(pDb,"sqlite3_prepare_v3",6);
}
const [xSql, xSqlLen] = __flexiString(sql, sqlLen);
switch(typeof xSql){
case 'string': return __prepare.basic(pDb, xSql, xSqlLen, prepFlags, ppStmt, null);
case 'number': return __prepare.full(pDb, xSql, xSqlLen, prepFlags, ppStmt, pzTail);
default:
return util.sqlite3_wasm_db_error(
pDb, capi.SQLITE_MISUSE,
"Invalid SQL argument type for sqlite3_prepare_v2/v3()."
);
}
};
/* Documented in the api object's initializer. */
capi.sqlite3_prepare_v2 = function(pDb, sql, sqlLen, ppStmt, pzTail){
return (5==arguments.length)
? capi.sqlite3_prepare_v3(pDb, sql, sqlLen, 0, ppStmt, pzTail)
: __dbArgcMismatch(pDb,"sqlite3_prepare_v2",5);
};
}/*sqlite3_prepare_v2/v3()*/;
/** /**
Install JS<->C struct bindings for the non-opaque struct types we Install JS<->C struct bindings for the non-opaque struct types we
@ -208,3 +303,4 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
sourceId: sqlite3.capi.sqlite3_sourceid() sourceId: sqlite3.capi.sqlite3_sourceid()
}); });
}); });

View File

@ -243,6 +243,17 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
); );
}; };
/**
If v is-a Array, its join('') result is returned. If
isSQLableTypedArray(v) then typedArrayToString(v) is
returned. Else v is returned as-is.
*/
const arrayToString = function(v){
if(isSQLableTypedArray(v)) return typedArrayToString(v);
else if(Array.isArray(v)) return v.join('');
return v;
};
/** /**
An Error subclass specifically for reporting Wasm-level malloc() An Error subclass specifically for reporting Wasm-level malloc()
failure and enabling clients to unambiguously identify such failure and enabling clients to unambiguously identify such
@ -350,15 +361,34 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
comments or an empty SQL expression, 0 is returned but the result comments or an empty SQL expression, 0 is returned but the result
output pointer will be NULL. output pointer will be NULL.
*/ */
sqlite3_prepare_v3: function(dbPtr, sql, sqlByteLen, prepFlags, sqlite3_prepare_v3: (dbPtr, sql, sqlByteLen, prepFlags,
stmtPtrPtr, strPtrPtr){}/*installed later*/, stmtPtrPtr, strPtrPtr)=>{}/*installed later*/,
/** /**
Equivalent to calling sqlite3_prapare_v3() with 0 as its 4th argument. Equivalent to calling sqlite3_prapare_v3() with 0 as its 4th argument.
*/ */
sqlite3_prepare_v2: function(dbPtr, sql, sqlByteLen, stmtPtrPtr, sqlite3_prepare_v2: (dbPtr, sql, sqlByteLen,
strPtrPtr){}/*installed later*/, stmtPtrPtr,strPtrPtr)=>{}/*installed later*/,
/**
This binding enables the callback argument to be a JavaScript.
If the callback is a function, then for the duration of the
sqlite3_exec() call, it installs a WASM-bound function which
acts as a proxy for the given callback. That proxy will
also perform a conversion of the callback's arguments from
`(char**)` to JS arrays of strings. However, for API
consistency's sake it will still honor the C-level
callback parameter order and will call it like:
`callback(pVoid, colCount, listOfValues, listOfColNames)`
If the callback is not a JS function then this binding performs
no translation of the callback, but the sql argument is still
converted to a WASM string for the call using the
"flexible-string" argument converter.
*/
sqlite3_exec: (pDb, sql, callback, pVoid, pErrMsg)=>{}/*installed later*/,
/** /**
Various internal-use utilities are added here as needed. They Various internal-use utilities are added here as needed. They
are bound to an object only so that we have access to them in are bound to an object only so that we have access to them in
@ -367,8 +397,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
removed. removed.
*/ */
util:{ util:{
isInt32, isTypedArray, isBindableTypedArray, isSQLableTypedArray, affirmBindableTypedArray, arrayToString, isBindableTypedArray,
affirmBindableTypedArray, typedArrayToString, isInt32, isSQLableTypedArray, isTypedArray,
typedArrayToString,
isMainWindow: ()=>{ isMainWindow: ()=>{
return self.window===self && self.document; return self.window===self && self.document;
} }
@ -614,10 +645,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
["sqlite3_errmsg", "string", "sqlite3*"], ["sqlite3_errmsg", "string", "sqlite3*"],
["sqlite3_error_offset", "int", "sqlite3*"], ["sqlite3_error_offset", "int", "sqlite3*"],
["sqlite3_errstr", "string", "int"], ["sqlite3_errstr", "string", "int"],
["sqlite3_exec", "int", "sqlite3*", "string", "*", "*", "**"], /*["sqlite3_exec", "int", "sqlite3*", "string", "*", "*", "**"
// TODO?: ^^^ add a wrapper around sqlite3_exec() which accepts a Handled seperately to perform translation of the callback
// JS callback function and handles the (un)installation of that into a WASM-usable one. ],*/
// function before/after the exec call.
["sqlite3_expanded_sql", "string", "sqlite3_stmt*"], ["sqlite3_expanded_sql", "string", "sqlite3_stmt*"],
["sqlite3_extended_errcode", "int", "sqlite3*"], ["sqlite3_extended_errcode", "int", "sqlite3*"],
["sqlite3_extended_result_codes", "int", "sqlite3*", "int"], ["sqlite3_extended_result_codes", "int", "sqlite3*", "int"],

View File

@ -186,7 +186,7 @@
// Custom db error message handling via sqlite3_prepare_v2/v3() // Custom db error message handling via sqlite3_prepare_v2/v3()
if(capi.wasm.exports.sqlite3_wasm_db_error){ if(capi.wasm.exports.sqlite3_wasm_db_error){
log("Testing custom error message via prepare_v3()..."); log("Testing custom error message via prepare_v3()...");
let rc = capi.sqlite3_prepare_v3(db.pointer, [/*invalid*/], -1, 0, null, null); let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
T.assert(capi.SQLITE_MISUSE === rc) T.assert(capi.SQLITE_MISUSE === rc)
.assert(0 === capi.sqlite3_errmsg(db.pointer).indexOf("Invalid SQL")); .assert(0 === capi.sqlite3_errmsg(db.pointer).indexOf("Invalid SQL"));
log("errmsg =",capi.sqlite3_errmsg(db.pointer)); log("errmsg =",capi.sqlite3_errmsg(db.pointer));
@ -253,7 +253,7 @@
const resultRows = []; const resultRows = [];
db.exec({ db.exec({
sql:new TextEncoder('utf-8').encode([ sql:new TextEncoder('utf-8').encode([
// ^^^ testing string-vs-typedarray handling in execMulti() // ^^^ testing string-vs-typedarray handling in exec()
"attach 'session' as foo;" /* name 'session' is magic for kvvfs! */, "attach 'session' as foo;" /* name 'session' is magic for kvvfs! */,
"create table foo.bar(a);", "create table foo.bar(a);",
"insert into foo.bar(a) values(1),(2),(3);", "insert into foo.bar(a) values(1),(2),(3);",
@ -266,6 +266,26 @@
T.assert(3===resultRows.length) T.assert(3===resultRows.length)
.assert(2===resultRows[1]); .assert(2===resultRows[1]);
T.assert(2===db.selectValue('select a from foo.bar where a>1 order by a')); T.assert(2===db.selectValue('select a from foo.bar where a>1 order by a'));
let colCount = 0, rowCount = 0;
const execCallback = function(pVoid, nCols, aVals, aNames){
colCount = nCols;
++rowCount;
T.assert(2===aVals.length)
.assert(2===aNames.length)
.assert(+(aVals[1]) === 2 * +(aVals[0]));
};
const capi = sqlite3.capi;
let rc = capi.sqlite3_exec(
db.pointer, "select a, a*2 from foo.bar", execCallback,
0, 0
);
T.assert(0===rc).assert(3===rowCount).assert(2===colCount);
rc = capi.sqlite3_exec(
db.pointer, "select a from foo.bar", ()=>{
toss("Testing throwing from exec() callback.");
}, 0, 0
);
T.assert(capi.SQLITE_ABORT === rc);
db.exec("detach foo"); db.exec("detach foo");
T.mustThrow(()=>db.exec("select * from foo.bar")); T.mustThrow(()=>db.exec("select * from foo.bar"));
}; };

View File

@ -247,7 +247,9 @@
runOneTest('close',{unlink:true},function(ev){ runOneTest('close',{unlink:true},function(ev){
ev = ev.result; ev = ev.result;
T.assert(undefined === ev.filename); T.assert(undefined === ev.filename);
logHtml('warning',"This is the final test.");
}); });
logHtml('warning',"Finished posting tests. Waiting on async results.");
}; };
const runTests = function(){ const runTests = function(){

View File

@ -1,5 +1,5 @@
C Add\ssqlite3.version\sobject.\sAdd\smore\sstate\sto\sthe\sWorker\s#1\sconfig-get\sresponse,\sincluding\ssqlite3.version. C Add\sJS\swrapper\sfor\ssqlite3_exec()\swhich\sknows\show\sto\shandle\sa\sJS\scallback.\sAdd\ssome\sconsole.error()\sreporting\sof\smodule-load\sfailures,\sas\sthey\sotherwise\soften\sget\ssilently\sswallowed\sup\sby\sthe\sloader's\smechanisms.\sAdd\s'flexible-string'\sJS-to-WASM\sargument\sconverter\swhich\sperforms\smore\sX-to-string\sconversions\sthan\sthe\s'string'\sarg\sconverter\sdoes.
D 2022-09-30T16:49:03.804 D 2022-09-30T20:35:37.991
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -479,16 +479,16 @@ F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api c6b05641d733227a995cc05a2ba7ddc9ef2323081ae0cae5ed1d1f83d5b54b36 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api c6b05641d733227a995cc05a2ba7ddc9ef2323081ae0cae5ed1d1f83d5b54b36
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md f54102d74cfde01ebe242fa1411e126a9cda8f19b3ac378afd1103b21abfad05 F ext/wasm/api/README.md f54102d74cfde01ebe242fa1411e126a9cda8f19b3ac378afd1103b21abfad05
F ext/wasm/api/extern-post-js.js b0df294159c290bec06cd67cce1a882d61944959ffe66a2f4ccbcb337e357781 F ext/wasm/api/extern-post-js.js dc68cbf552d8ea085181400a6963907c32e0b088b03ffd8969b1869fea246629
F ext/wasm/api/extern-pre-js.js 20143b16b672d0a576fbf768a786d12ee1f84e222126477072389b992542a5b2 F ext/wasm/api/extern-pre-js.js 20143b16b672d0a576fbf768a786d12ee1f84e222126477072389b992542a5b2
F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b
F ext/wasm/api/sqlite3-api-cleanup.js 98905936119a555659b5cf43844211809ab9f436c52a569004e5585d2842b5c2 F ext/wasm/api/sqlite3-api-cleanup.js 5d22d1d3818ecacb23bfa223d5970cd0617d8cdbb48c8bc4bbd463f05b021a99
F ext/wasm/api/sqlite3-api-glue.js 90206acd5cf556bd8a7a9275619aa680c9075ad8072ed1e18f47fc1d5cfbcf26 F ext/wasm/api/sqlite3-api-glue.js ead29e6008ba148e7c67ad2bd928819dc72313ad2dcd34510cc61e089ee01c4e
F ext/wasm/api/sqlite3-api-oo1.js 9caed0757a5e039ed92467e827fd3ca347fa08f19fe086fcbdd14a4ebe9c2f01 F ext/wasm/api/sqlite3-api-oo1.js 9caed0757a5e039ed92467e827fd3ca347fa08f19fe086fcbdd14a4ebe9c2f01
F ext/wasm/api/sqlite3-api-opfs.js 1b097808b7b081b0f0700cf97d49ef19760e401706168edff9cd45cf9169f541 F ext/wasm/api/sqlite3-api-opfs.js 1b097808b7b081b0f0700cf97d49ef19760e401706168edff9cd45cf9169f541
F ext/wasm/api/sqlite3-api-prologue.js 3a93497a9bc542c7202f32063cd070aa9c4cd03171a5e354cf99dd4357585b7a F ext/wasm/api/sqlite3-api-prologue.js cac3bc095171dca4aaf3611e0dd60a850c8e9fbeeeba8f21792ed1948d24dacc
F ext/wasm/api/sqlite3-api-worker1.js 2e8a037a76d20c7653e5a392d9830f17a22ce6736ffd0597aa39b69d1c01ad2c F ext/wasm/api/sqlite3-api-worker1.js 2e8a037a76d20c7653e5a392d9830f17a22ce6736ffd0597aa39b69d1c01ad2c
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
F ext/wasm/api/sqlite3-wasm.c 336389b23c9b83763177499e49a0967949c392b2f7d84fbbb52ad6678e159f18 F ext/wasm/api/sqlite3-wasm.c 336389b23c9b83763177499e49a0967949c392b2f7d84fbbb52ad6678e159f18
@ -530,9 +530,9 @@ F ext/wasm/test-opfs-vfs.js a59ff9210b17d46b0c6fbf6a0ba60143c033327865f2e556e14f
F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893 F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
F ext/wasm/testing-worker1-promiser.js ee1ac4950720c07541e791b7f35bdf420e8ab81a74049cc65394371b0c53c480 F ext/wasm/testing-worker1-promiser.js ee1ac4950720c07541e791b7f35bdf420e8ab81a74049cc65394371b0c53c480
F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d7669fb17fcae F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d7669fb17fcae
F ext/wasm/testing1.js 06b9a439ada636c5478c581c86b2b968f799e0468eae54dc5a4565dfd7afbb88 F ext/wasm/testing1.js 5584e9b68f797dbc0f6161360f2c6840169533813d92c74d355a3e78dd5bb539
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3 F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
F ext/wasm/testing2.js 34737da985c4cbd4812b2e7f200942662cae991c5a58ffa5d0350be089d0d410 F ext/wasm/testing2.js 88f40ef3cd8201bdadd120a711c36bbf0ce56cc0eab1d5e7debb71fed7822494
F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
@ -2029,8 +2029,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 1e09efe7fa15b8908f8b8353164a8361de778e27ea6c0b11c402bf4e1c56333d P 711f458d188a0dbe6612069c856ade29323ab426dfa4f80e7b82757ccc474cb8
R 4c776ad1a7aec6f0bcde0b14554ad6b2 R 84d8e08f60a70faceba1089503bc1c19
U stephan U stephan
Z 125edfcbc5b4725eac67cee184f7f0b1 Z f9cd8bd536b2dd8409558133f7a063eb
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
711f458d188a0dbe6612069c856ade29323ab426dfa4f80e7b82757ccc474cb8 96818aa83f4ccc574f558231249ecbdd39763b4351cf4cf6d33f53774a3ee5e6