Reimplement JS's sqlite3_bind_text/blob() with hand-written bindings to permit more flexible inputs. Add automated JS-to-C function conversion to sqlite3_busy_handler(). sqlite3.wasm.xWrap()'s '*' argument conversion no longer treats JS strings as C-strings: those conversions require explicit opt-in via the 'string' converter (or equivalent).
FossilOrigin-Name: 96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6
This commit is contained in:
parent
ab9c2d571e
commit
027afccdcd
@ -42,10 +42,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
wasm.bindingSignatures = [
|
||||
// Please keep these sorted by function name!
|
||||
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
|
||||
["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
|
||||
/* TODO: we should arguably write a custom wrapper which knows
|
||||
how to handle Blob, TypedArrays, and JS strings. */
|
||||
],
|
||||
/* sqlite3_bind_blob() and sqlite3_bind_text() have hand-written
|
||||
bindings to permit more flexible inputs. */
|
||||
["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"],
|
||||
["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"],
|
||||
["sqlite3_bind_null",undefined, "sqlite3_stmt*", "int"],
|
||||
@ -53,16 +51,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"],
|
||||
["sqlite3_bind_pointer", "int",
|
||||
"sqlite3_stmt*", "int", "*", "string:static", "*"],
|
||||
["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "*"
|
||||
/* We should arguably create a hand-written binding of
|
||||
bind_text() which does more flexible text conversion, along
|
||||
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({
|
||||
signature: 'i(pi)',
|
||||
contextKey: (argIndex,argv)=>'sqlite3@'+argv[0]
|
||||
}),
|
||||
"*"
|
||||
]],
|
||||
["sqlite3_busy_timeout","int", "sqlite3*", "int"],
|
||||
["sqlite3_close_v2", "int", "sqlite3*"],
|
||||
["sqlite3_changes", "int", "sqlite3*"],
|
||||
@ -779,6 +775,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
if(1){/* Special-case handling of sqlite3_prepare_v2() and
|
||||
sqlite3_prepare_v3() */
|
||||
|
||||
/**
|
||||
Helper for string:flexible conversions which require a
|
||||
byte-length counterpart argument. Passed a value and its
|
||||
@ -802,32 +799,33 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
/**
|
||||
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",
|
||||
"**", "**"]);
|
||||
const __prepare = {
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
full: wasm.xWrap('sqlite3_prepare_v3',
|
||||
"int", ["sqlite3*", "*", "int", "int",
|
||||
"**", "**"])
|
||||
};
|
||||
|
||||
/* Documented in the capi object's initializer. */
|
||||
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
|
||||
@ -852,7 +850,80 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
? capi.sqlite3_prepare_v3(pDb, sql, sqlLen, 0, ppStmt, pzTail)
|
||||
: __dbArgcMismatch(pDb,"sqlite3_prepare_v2",f.length);
|
||||
};
|
||||
}/*sqlite3_prepare_v2/v3()*/;
|
||||
|
||||
}/*sqlite3_prepare_v2/v3()*/
|
||||
|
||||
{/*sqlite3_bind_text/blob()*/
|
||||
const __bindText = wasm.xWrap("sqlite3_bind_text", "int", [
|
||||
"sqlite3_stmt*", "int", "string", "int", "*"
|
||||
]);
|
||||
const __bindBlob = wasm.xWrap("sqlite3_bind_blob", "int", [
|
||||
"sqlite3_stmt*", "int", "*", "int", "*"
|
||||
]);
|
||||
|
||||
/** Documented in the capi object's initializer. */
|
||||
capi.sqlite3_bind_text = function f(pStmt, iCol, text, nText, xDestroy){
|
||||
if(f.length!==arguments.length){
|
||||
return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt),
|
||||
"sqlite3_bind_text", f.length);
|
||||
}else if(wasm.isPtr(text) || null===text){
|
||||
return __bindText(pStmt, iCol, text, nText, xDestroy);
|
||||
}else if(text instanceof ArrayBuffer){
|
||||
text = new Uint8Array(text);
|
||||
}else if(Array.isArray(pMem)){
|
||||
text = pMem.join('');
|
||||
}
|
||||
let p, n;
|
||||
try {
|
||||
if(util.isSQLableTypedArray(text)){
|
||||
p = wasm.allocFromTypedArray(text);
|
||||
n = text.byteLength;
|
||||
}else if('string'===typeof text){
|
||||
[p, n] = wasm.allocCString(text);
|
||||
}else{
|
||||
return util.sqlite3_wasm_db_error(
|
||||
capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE,
|
||||
"Invalid 3rd argument type for sqlite3_bind_text()."
|
||||
);
|
||||
}
|
||||
return __bindText(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT);
|
||||
}finally{
|
||||
wasm.dealloc(p);
|
||||
}
|
||||
}/*sqlite3_bind_text()*/;
|
||||
|
||||
/** Documented in the capi object's initializer. */
|
||||
capi.sqlite3_bind_blob = function f(pStmt, iCol, pMem, nMem, xDestroy){
|
||||
if(f.length!==arguments.length){
|
||||
return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt),
|
||||
"sqlite3_bind_blob", f.length);
|
||||
}else if(wasm.isPtr(pMem) || null===pMem){
|
||||
return __bindBlob(pStmt, iCol, pMem, nMem, xDestroy);
|
||||
}else if(pMem instanceof ArrayBuffer){
|
||||
pMem = new Uint8Array(pMem);
|
||||
}else if(Array.isArray(pMem)){
|
||||
pMem = pMem.join('');
|
||||
}
|
||||
let p, n;
|
||||
try{
|
||||
if(util.isBindableTypedArray(pMem)){
|
||||
p = wasm.allocFromTypedArray(pMem);
|
||||
n = nMem>=0 ? nMem : pMem.byteLength;
|
||||
}else if('string'===typeof pMem){
|
||||
[p, n] = wasm.allocCString(pMem);
|
||||
}else{
|
||||
return util.sqlite3_wasm_db_error(
|
||||
capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE,
|
||||
"Invalid 3rd argument type for sqlite3_bind_blob()."
|
||||
);
|
||||
}
|
||||
return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT);
|
||||
}finally{
|
||||
wasm.dealloc(p);
|
||||
}
|
||||
}/*sqlite3_bind_blob()*/;
|
||||
|
||||
}/*sqlite3_bind_text/blob()*/
|
||||
|
||||
{/* sqlite3_set_authorizer() */
|
||||
const __ssa = wasm.xWrap("sqlite3_set_authorizer", 'int', [
|
||||
|
@ -1332,8 +1332,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}else if(!util.isBindableTypedArray(val)){
|
||||
toss3("Binding a value as a blob requires",
|
||||
"that it be a string, Uint8Array, or Int8Array.");
|
||||
}else if(1){
|
||||
/* _Hypothetically_ more efficient than the impl in the 'else' block. */
|
||||
}else{
|
||||
const stack = wasm.scopedAllocPush();
|
||||
try{
|
||||
const pBlob = wasm.scopedAlloc(val.byteLength || 1);
|
||||
@ -1343,14 +1342,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}finally{
|
||||
wasm.scopedAllocPop(stack);
|
||||
}
|
||||
}else{
|
||||
const pBlob = wasm.allocFromTypedArray(val);
|
||||
try{
|
||||
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
||||
capi.SQLITE_TRANSIENT);
|
||||
}finally{
|
||||
wasm.dealloc(pBlob);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -417,6 +417,92 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
};
|
||||
|
||||
Object.assign(capi, {
|
||||
/**
|
||||
sqlite3_bind_blob() works exactly like its C counterpart unless
|
||||
its 3rd argument is one of:
|
||||
|
||||
- JS string: the 3rd argument is converted to a C string, the
|
||||
4th argument is ignored, and the C-string's length is used
|
||||
in its place.
|
||||
|
||||
- Array: converted to a string as defined for "flexible
|
||||
strings" and then it's treated as a JS string.
|
||||
|
||||
- Int8Array or Uint8Array: wasm.allocFromTypedArray() is used to
|
||||
conver the memory to the WASM heap. If the 4th argument is
|
||||
0 or greater, it is used as-is, otherwise the array's byteLength
|
||||
value is used. This is an exception to the C API's undefined
|
||||
behavior for a negative 4th argument, but results are undefined
|
||||
if the given 4th argument value is greater than the byteLength
|
||||
of the input array.
|
||||
|
||||
- If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
|
||||
treated as that type.
|
||||
|
||||
In all of those cases, the final argument (text destructor) is
|
||||
ignored and capi.SQLITE_TRANSIENT is assumed.
|
||||
|
||||
A 3rd argument of `null` is treated as if it were a WASM pointer
|
||||
of 0.
|
||||
|
||||
If the 3rd argument is neither a WASM pointer nor one of the
|
||||
above-described types, capi.SQLITE_MISUSE is returned.
|
||||
|
||||
The first argument may be either an `sqlite3_stmt*` WASM
|
||||
pointer or an sqlite3.oo1.Stmt instance.
|
||||
|
||||
For consistency with the C API, it requires the same number of
|
||||
arguments. It returns capi.SQLITE_MISUSE if passed any other
|
||||
argument count.
|
||||
*/
|
||||
sqlite3_bind_blob: undefined/*installed later*/,
|
||||
|
||||
/**
|
||||
sqlite3_bind_text() works exactly like its C counterpart unless
|
||||
its 3rd argument is one of:
|
||||
|
||||
- JS string: the 3rd argument is converted to a C string, the
|
||||
4th argument is ignored, and the C-string's length is used
|
||||
in its place.
|
||||
|
||||
- Array: converted to a string as defined for "flexible
|
||||
strings". The 4th argument is ignored and a value of -1
|
||||
is assumed.
|
||||
|
||||
- Int8Array or Uint8Array: is assumed to contain UTF-8 text, is
|
||||
converted to a string. The 4th argument is ignored, replaced
|
||||
by the array's byteLength value.
|
||||
|
||||
- If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
|
||||
treated as that type.
|
||||
|
||||
In each of those cases, the final argument (text destructor) is
|
||||
ignored and capi.SQLITE_TRANSIENT is assumed.
|
||||
|
||||
A 3rd argument of `null` is treated as if it were a WASM pointer
|
||||
of 0.
|
||||
|
||||
If the 3rd argument is neither a WASM pointer nor one of the
|
||||
above-described types, capi.SQLITE_MISUSE is returned.
|
||||
|
||||
The first argument may be either an `sqlite3_stmt*` WASM
|
||||
pointer or an sqlite3.oo1.Stmt instance.
|
||||
|
||||
For consistency with the C API, it requires the same number of
|
||||
arguments. It returns capi.SQLITE_MISUSE if passed any other
|
||||
argument count.
|
||||
|
||||
If client code needs to bind partial strings, it needs to
|
||||
either parcel the string up before passing it in here or it
|
||||
must pass in a WASM pointer for the 3rd argument and a valid
|
||||
4th-argument value, taking care not to pass a value which
|
||||
truncates a multi-byte UTF-8 character. When passing
|
||||
WASM-format strings, it is important that the final argument be
|
||||
valid or unexpected content can result can result, or even a
|
||||
crash if the application reads past the WASM heap bounds.
|
||||
*/
|
||||
sqlite3_bind_text: undefined/*installed later*/,
|
||||
|
||||
/**
|
||||
sqlite3_create_function_v2() differs from its native
|
||||
counterpart only in the following ways:
|
||||
@ -525,18 +611,18 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH`
|
||||
flag.
|
||||
*/
|
||||
sqlite3_create_function_v2: function(
|
||||
sqlite3_create_function_v2: (
|
||||
pDb, funcName, nArg, eTextRep, pApp,
|
||||
xFunc, xStep, xFinal, xDestroy
|
||||
){/*installed later*/},
|
||||
)=>{/*installed later*/},
|
||||
/**
|
||||
Equivalent to passing the same arguments to
|
||||
sqlite3_create_function_v2(), with 0 as the final argument.
|
||||
*/
|
||||
sqlite3_create_function:function(
|
||||
sqlite3_create_function: (
|
||||
pDb, funcName, nArg, eTextRep, pApp,
|
||||
xFunc, xStep, xFinal
|
||||
){/*installed later*/},
|
||||
)=>{/*installed later*/},
|
||||
/**
|
||||
The sqlite3_create_window_function() JS wrapper differs from
|
||||
its native implementation in the exact same way that
|
||||
@ -544,10 +630,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
xInverse(), is treated identically to xStep() by the wrapping
|
||||
layer.
|
||||
*/
|
||||
sqlite3_create_window_function: function(
|
||||
sqlite3_create_window_function: (
|
||||
pDb, funcName, nArg, eTextRep, pApp,
|
||||
xStep, xFinal, xValue, xInverse, xDestroy
|
||||
){/*installed later*/},
|
||||
)=>{/*installed later*/},
|
||||
/**
|
||||
The sqlite3_prepare_v3() binding handles two different uses
|
||||
with differing JS/WASM semantics:
|
||||
@ -669,7 +755,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
toss3,
|
||||
typedArrayPart
|
||||
};
|
||||
|
||||
|
||||
Object.assign(wasm, {
|
||||
/**
|
||||
Emscripten APIs have a deep-seated assumption that all pointers
|
||||
|
@ -1406,7 +1406,8 @@ self.WhWasmUtilInstaller = function(target){
|
||||
.set('int', xArg.get('i32'))
|
||||
.set('null', (i)=>i)
|
||||
.set(null, xArg.get('null'))
|
||||
.set('**', __xArgPtr);
|
||||
.set('**', __xArgPtr)
|
||||
.set('*', __xArgPtr);
|
||||
xResult.set('*', __xArgPtr)
|
||||
.set('pointer', __xArgPtr)
|
||||
.set('number', (v)=>Number(v))
|
||||
@ -1448,23 +1449,23 @@ self.WhWasmUtilInstaller = function(target){
|
||||
if('string'===typeof v) return target.scopedAllocCString(v);
|
||||
return v ? __xArgPtr(v) : null;
|
||||
};
|
||||
xArg.set('string', __xArgString);
|
||||
xArg.set('utf8', __xArgString);
|
||||
xArg.set('pointer', __xArgString);
|
||||
xArg.set('*', __xArgString);
|
||||
xArg.set('string', __xArgString)
|
||||
.set('utf8', __xArgString)
|
||||
.set('pointer', __xArgString);
|
||||
//xArg.set('*', __xArgString);
|
||||
|
||||
xResult.set('string', (i)=>target.cstrToJs(i));
|
||||
xResult.set('utf8', xResult.get('string'));
|
||||
xResult.set('string:dealloc', (i)=>{
|
||||
try { return i ? target.cstrToJs(i) : null }
|
||||
finally{ target.dealloc(i) }
|
||||
});
|
||||
xResult.set('utf8:dealloc', xResult.get('string:dealloc'));
|
||||
xResult.set('json', (i)=>JSON.parse(target.cstrToJs(i)));
|
||||
xResult.set('json:dealloc', (i)=>{
|
||||
try{ return i ? JSON.parse(target.cstrToJs(i)) : null }
|
||||
finally{ target.dealloc(i) }
|
||||
});
|
||||
xResult.set('string', (i)=>target.cstrToJs(i))
|
||||
.set('utf8', xResult.get('string'))
|
||||
.set('string:dealloc', (i)=>{
|
||||
try { return i ? target.cstrToJs(i) : null }
|
||||
finally{ target.dealloc(i) }
|
||||
})
|
||||
.set('utf8:dealloc', xResult.get('string:dealloc'))
|
||||
.set('json', (i)=>JSON.parse(target.cstrToJs(i)))
|
||||
.set('json:dealloc', (i)=>{
|
||||
try{ return i ? JSON.parse(target.cstrToJs(i)) : null }
|
||||
finally{ target.dealloc(i) }
|
||||
});
|
||||
|
||||
/**
|
||||
Internal-use-only base class for FuncPtrAdapter and potentially
|
||||
@ -1748,10 +1749,13 @@ self.WhWasmUtilInstaller = function(target){
|
||||
- `N*` (args): a type name in the form `N*`, where N is a numeric
|
||||
type name, is treated the same as WASM pointer.
|
||||
|
||||
- `*` and `pointer` (args): have multple semantics. They
|
||||
behave exactly as described below for `string` args.
|
||||
- `*` and `pointer` (args): are assumed to be WASM pointer values
|
||||
and are returned coerced to an appropriately-sized pointer
|
||||
value (i32 or i64). Non-numeric values will coerce to 0 and
|
||||
out-of-range values will have undefined results (just as with
|
||||
any pointer misuse).
|
||||
|
||||
- `*` and `pointer` (results): are aliases for the current
|
||||
- `*` and `pointer` (results): aliases for the current
|
||||
WASM pointer numeric type.
|
||||
|
||||
- `**` (args): is simply a descriptive alias for the WASM pointer
|
||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Internal\sJS\scleanups.\sCorrect\spart\sof\s[ac136925a645]\sto\saccount\sfor\sthe\seTextRep\sflag\sbeing\sable\sto\shold\sflags\sother\sthan\sthe\sencoding.
|
||||
D 2022-12-23T21:10:49.493
|
||||
C Reimplement\sJS's\ssqlite3_bind_text/blob()\swith\shand-written\sbindings\sto\spermit\smore\sflexible\sinputs.\sAdd\sautomated\sJS-to-C\sfunction\sconversion\sto\ssqlite3_busy_handler().\ssqlite3.wasm.xWrap()'s\s'*'\sargument\sconversion\sno\slonger\streats\sJS\sstrings\sas\sC-strings:\sthose\sconversions\srequire\sexplicit\sopt-in\svia\sthe\s'string'\sconverter\s(or\sequivalent).
|
||||
D 2022-12-23T23:46:33.608
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -503,9 +503,9 @@ 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 f50211dc11f1debf972cdaea87cb4df9772022828072e7100cf5025d1dca2a78
|
||||
F ext/wasm/api/sqlite3-api-oo1.js 4cce9671e8a31ac9b76bd8559e7827ccc2b121734e460fa9c7d243735a771ec8
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 789639d256e3134563c5c9be25ade28b40e06e783885d26cccc01cd1ed4b820d
|
||||
F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9
|
||||
F ext/wasm/api/sqlite3-api-oo1.js c2a3e310f993a632b6c5da0c49b0635863a73df60c4f9fc0a30648f25e4ec32a
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d
|
||||
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 97807770ec452fdcaa48509c5decd3a2c1e3001164a62a3223a347f66967533e
|
||||
F ext/wasm/common/whwasmutil.js 700fb1b702986522d2177fe8247bfbab3040e82cb4f6c35e929c4c85fbd7ffc5
|
||||
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 deffe6fb211410fa1a1fbca824a52b4e09b54d4b4f4a4e12d71c9e4b7e8606fb
|
||||
R 537077e8e7a576993086a957d5c52d05
|
||||
P 1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f
|
||||
R 0557f08bf576b7be78ec588d2742348d
|
||||
U stephan
|
||||
Z 379d99233453fc912eb71dcbaf16b8ce
|
||||
Z 4e12d5aedea06f895991428eb871a6d7
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f
|
||||
96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6
|
Loading…
Reference in New Issue
Block a user